From 48c81ac7e0bbc3d9464278aad47b5a6e93f80575 Mon Sep 17 00:00:00 2001 From: 0xCipherCoder Date: Sat, 11 Jan 2025 14:41:55 +0530 Subject: [PATCH] Added fix for the issue --- src/langchain/3land/create_collection.ts | 18 +++-- src/langchain/3land/create_single.ts | 46 ++++++++----- src/langchain/adrena/close_trade.ts | 34 +++++---- src/langchain/adrena/open_trade.ts | 26 +++++-- src/langchain/adrena/types.ts | 29 -------- src/langchain/agent/create_image.ts | 18 +++-- src/langchain/agent/types.ts | 9 --- src/langchain/agent/wallet_address.ts | 18 ++--- src/langchain/bonfida/get_domain.ts | 21 ++++-- src/langchain/bonfida/main_domain.ts | 20 ++++-- src/langchain/bonfida/register_domain.ts | 44 +++++++++--- src/langchain/bonfida/resolve_domain.ts | 21 ++++-- src/langchain/bonfida/types.ts | 45 ------------ src/langchain/common/base.ts | 17 ----- src/langchain/common/index.ts | 2 - src/langchain/common/types.ts | 5 -- .../dexscreener/token_data_ticker.ts | 16 +++-- src/langchain/flash/flash_close.ts | 39 ++++++++--- src/langchain/flash/flash_open.ts | 69 +++++++++++++++---- src/langchain/flash/index.ts | 1 - src/langchain/flash/types.ts | 25 ------- src/langchain/gibwork/create_task.ts | 47 ++++++++----- src/langchain/gibwork/index.ts | 1 - src/langchain/gibwork/types.ts | 16 ----- src/langchain/index.ts | 8 +-- src/langchain/jupiter/fetch_price.ts | 21 ++++-- src/langchain/jupiter/index.ts | 1 - src/langchain/jupiter/stake.ts | 18 +++-- src/langchain/jupiter/token_data.ts | 16 ++++- src/langchain/jupiter/trade.ts | 27 +++++--- src/langchain/jupiter/types.ts | 19 ----- .../lightprotocol/compressed_airdrop.ts | 31 ++++++--- src/langchain/lulo/index.ts | 1 - src/langchain/lulo/lend_asset.ts | 21 ++++-- src/langchain/lulo/types.ts | 10 --- src/langchain/manifest/batch_order.ts | 69 +++++++++++-------- src/langchain/manifest/cancel_orders.ts | 21 ++++-- src/langchain/manifest/index.ts | 1 - src/langchain/manifest/limit_order.ts | 31 ++++++--- src/langchain/manifest/manifest_market.ts | 29 +++++--- src/langchain/manifest/types.ts | 11 --- src/langchain/manifest/withdraw.ts | 15 ++-- src/langchain/metaplex/deploy_collection.ts | 27 +++++--- src/langchain/metaplex/deploy_token.ts | 29 +++++--- src/langchain/metaplex/index.ts | 1 - src/langchain/metaplex/mint_nft.ts | 39 +++++++---- src/langchain/metaplex/types.ts | 33 --------- src/langchain/onsol/get_all_tld.ts | 9 ++- src/langchain/onsol/index.ts | 1 - src/langchain/onsol/owned_domains.ts | 20 ++++-- src/langchain/onsol/resolve_all_domains.ts | 22 ++++-- src/langchain/onsol/tld_domains.ts | 20 ++++-- src/langchain/onsol/types.ts | 45 ------------ src/langchain/openbook/index.ts | 1 - src/langchain/openbook/openbook_market.ts | 32 ++++++--- src/langchain/openbook/types.ts | 6 -- src/langchain/orca/index.ts | 1 - src/langchain/orca/orca_centered_position.ts | 39 ++++++++--- src/langchain/orca/orca_clmm.ts | 32 ++++++--- src/langchain/orca/orca_fetch_positions.ts | 26 ++++--- src/langchain/orca/orca_position.ts | 26 ++++--- src/langchain/orca/orca_single_sided_pool.ts | 38 ++++++---- .../orca/orca_single_sided_position.ts | 45 ++++++++---- src/langchain/orca/types.ts | 51 -------------- src/langchain/pumpfun/launch_pumpfun_token.ts | 9 ++- src/langchain/pyth/index.ts | 1 - src/langchain/pyth/pyth_price.ts | 15 ++-- src/langchain/pyth/types.ts | 11 --- src/langchain/raydium/raydium_amm.ts | 31 ++++++--- src/langchain/raydium/raydium_clmm.ts | 35 ++++++---- src/langchain/raydium/raydium_cpmm.ts | 38 ++++++---- src/langchain/rugcheck/index.ts | 1 - .../rugcheck/token_report_detailed.ts | 18 +++-- .../rugcheck/token_report_summary.ts | 18 +++-- src/langchain/rugcheck/types.ts | 17 ----- src/langchain/sendarcade/index.ts | 1 - .../sendarcade/rock_paper_scissors.ts | 38 ++++++++-- src/langchain/sendarcade/types.ts | 4 -- src/langchain/solana/balance.ts | 22 +++--- src/langchain/solana/balance_other.ts | 28 +++++--- src/langchain/solana/close_empty_accounts.ts | 16 +++-- src/langchain/solana/get_tps.ts | 18 ++--- src/langchain/solana/index.ts | 1 - src/langchain/solana/request_funds.ts | 18 +++-- src/langchain/solana/transfer.ts | 31 ++++++--- src/langchain/solana/types.ts | 13 ---- src/langchain/solayer/restake.ts | 18 +++-- .../squads_multisig/approve_proposal.ts | 9 ++- .../squads_multisig/create_multisig.ts | 9 ++- .../squads_multisig/create_proposal.ts | 9 ++- .../squads_multisig/deposit_to_multisig.ts | 9 ++- .../squads_multisig/execute_proposal.ts | 9 ++- .../squads_multisig/reject_proposal.ts | 9 ++- .../squads_multisig/transfer_from_multisig.ts | 9 ++- src/langchain/tensor/cancel_listing.ts | 24 ++++--- src/langchain/tensor/list_nft.ts | 34 +++++---- src/langchain/tensor/types.ts | 22 ------ src/langchain/tiplink/index.ts | 1 - src/langchain/tiplink/tiplink.ts | 30 +++++--- src/langchain/tiplink/types.ts | 13 ---- 100 files changed, 1133 insertions(+), 936 deletions(-) delete mode 100644 src/langchain/adrena/types.ts delete mode 100644 src/langchain/agent/types.ts delete mode 100644 src/langchain/bonfida/types.ts delete mode 100644 src/langchain/common/base.ts delete mode 100644 src/langchain/common/index.ts delete mode 100644 src/langchain/common/types.ts delete mode 100644 src/langchain/flash/types.ts delete mode 100644 src/langchain/gibwork/types.ts delete mode 100644 src/langchain/jupiter/types.ts delete mode 100644 src/langchain/lulo/types.ts delete mode 100644 src/langchain/manifest/types.ts delete mode 100644 src/langchain/metaplex/types.ts delete mode 100644 src/langchain/onsol/types.ts delete mode 100644 src/langchain/openbook/types.ts delete mode 100644 src/langchain/orca/types.ts delete mode 100644 src/langchain/pyth/types.ts delete mode 100644 src/langchain/rugcheck/types.ts delete mode 100644 src/langchain/sendarcade/types.ts delete mode 100644 src/langchain/solana/types.ts delete mode 100644 src/langchain/tensor/types.ts delete mode 100644 src/langchain/tiplink/types.ts diff --git a/src/langchain/3land/create_collection.ts b/src/langchain/3land/create_collection.ts index 9b95682..111dd4c 100644 --- a/src/langchain/3land/create_collection.ts +++ b/src/langchain/3land/create_collection.ts @@ -1,10 +1,11 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import { CreateCollectionOptions, StoreInitOptions, } from "@3land/listings-sdk/dist/types/implementation/implementationTypes"; -export class Solana3LandCreateCollection extends BaseSolanaTool { +export class Solana3LandCreateCollection extends Tool { name = "3land_minting_tool"; description = `Creates an NFT Collection that you can visit on 3.land's website (3.land/collection/{collectionAccount}) @@ -15,7 +16,12 @@ export class Solana3LandCreateCollection extends BaseSolanaTool { collectionName (required): the name of the collection collectionDescription (required): the description of the collection mainImageUrl (required): the image of the collection - coverImageUrl (optional): the cover image of the collection`; + coverImageUrl (optional): the cover image of the collection + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -52,7 +58,11 @@ export class Solana3LandCreateCollection extends BaseSolanaTool { transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/3land/create_single.ts b/src/langchain/3land/create_single.ts index a79f9e8..25db42e 100644 --- a/src/langchain/3land/create_single.ts +++ b/src/langchain/3land/create_single.ts @@ -1,26 +1,32 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import { CreateSingleOptions, StoreInitOptions, } from "@3land/listings-sdk/dist/types/implementation/implementationTypes"; -export class Solana3LandCreateSingle extends BaseSolanaTool { +export class Solana3LandCreateSingle extends Tool { name = "3land_minting_tool"; description = `Creates an NFT and lists it on 3.land's website - - Inputs: - privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string - collectionAccount (optional): represents the account for the nft collection - itemName (required): the name of the NFT - sellerFee (required): the fee of the seller - itemAmount (required): the amount of the NFTs that can be minted - itemDescription (required): the description of the NFT - traits (required): the traits of the NFT [{trait_type: string, value: string}] - price (required): the price of the item, if is 0 the listing will be free - mainImageUrl (required): the main image of the NFT - coverImageUrl (optional): the cover image of the NFT - splHash (optional): the hash of the spl token, if not provided listing will be in $SOL - isMainnet (required): defines is the tx takes places in mainnet`; + + Inputs: + privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string + collectionAccount (optional): represents the account for the nft collection + itemName (required): the name of the NFT + sellerFee (required): the fee of the seller + itemAmount (required): the amount of the NFTs that can be minted + itemDescription (required): the description of the NFT + traits (required): the traits of the NFT [{trait_type: string, value: string}] + price (required): the price of the item, if is 0 the listing will be free + mainImageUrl (required): the main image of the NFT + coverImageUrl (optional): the cover image of the NFT + splHash (optional): the hash of the spl token, if not provided listing will be in $SOL + isMainnet (required): defines is the tx takes places in mainnet + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -62,20 +68,24 @@ export class Solana3LandCreateSingle extends BaseSolanaTool { if (!collectionAccount) { throw new Error("Collection account is required"); } + const tx = await this.solanaKit.create3LandNft( optionsWithBase58, collectionAccount, createItemOptions, isMainnet, ); - return JSON.stringify({ status: "success", message: `Created listing successfully ${tx}`, transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/adrena/close_trade.ts b/src/langchain/adrena/close_trade.ts index c434b1b..7380e89 100644 --- a/src/langchain/adrena/close_trade.ts +++ b/src/langchain/adrena/close_trade.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { PerpTradeResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaPerpCloseTradeTool extends BaseSolanaTool { +export class SolanaPerpCloseTradeTool extends Tool { name = "solana_close_perp_trade"; description = `This tool can be used to close perpetuals trade ( It uses Adrena Protocol ). @@ -11,29 +11,39 @@ export class SolanaPerpCloseTradeTool extends BaseSolanaTool { price?: number, eg 100 (optional) side: string, eg: "long" or "short"`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = JSON.parse(input); + const parsedInput = JSON.parse(input); const tx = - params.side === "long" + parsedInput.side === "long" ? await this.solanaKit.closePerpTradeLong({ - price: params.price, - tradeMint: new PublicKey(params.tradeMint), + price: parsedInput.price, + tradeMint: new PublicKey(parsedInput.tradeMint), }) : await this.solanaKit.closePerpTradeShort({ - price: params.price, - tradeMint: new PublicKey(params.tradeMint), + price: parsedInput.price, + tradeMint: new PublicKey(parsedInput.tradeMint), }); return JSON.stringify({ status: "success", message: "Perpetual trade closed successfully", transaction: tx, - ...params, - } as PerpTradeResponse); + price: parsedInput.price, + tradeMint: new PublicKey(parsedInput.tradeMint), + side: parsedInput.side, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/adrena/open_trade.ts b/src/langchain/adrena/open_trade.ts index 38a79ae..18f3ecc 100644 --- a/src/langchain/adrena/open_trade.ts +++ b/src/langchain/adrena/open_trade.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { PerpTradeResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaPerpOpenTradeTool extends BaseSolanaTool { +export class SolanaPerpOpenTradeTool extends Tool { name = "solana_open_perp_trade"; description = `This tool can be used to open perpetuals trade ( It uses Adrena Protocol ). @@ -15,6 +15,10 @@ export class SolanaPerpOpenTradeTool extends BaseSolanaTool { slippage?: number, eg 0.3 (optional) side: string, eg: "long" or "short"`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const parsedInput = JSON.parse(input); @@ -42,10 +46,20 @@ export class SolanaPerpOpenTradeTool extends BaseSolanaTool { status: "success", message: "Perpetual trade opened successfully", transaction: tx, - ...parsedInput, - } as PerpTradeResponse); + price: parsedInput.price, + collateralAmount: parsedInput.collateralAmount, + collateralMint: new PublicKey(parsedInput.collateralMint), + leverage: parsedInput.leverage, + tradeMint: new PublicKey(parsedInput.tradeMint), + slippage: parsedInput.slippage, + side: parsedInput.side, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/adrena/types.ts b/src/langchain/adrena/types.ts deleted file mode 100644 index 90f0d53..0000000 --- a/src/langchain/adrena/types.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface PerpCloseTradeInput { - tradeMint: string; - price?: number; - side: "long" | "short"; -} - -export interface PerpOpenTradeInput { - collateralAmount: number; - collateralMint?: string; - tradeMint?: string; - leverage?: number; - price?: number; - slippage?: number; - side: "long" | "short"; -} - -export interface PerpTradeResponse extends BaseToolResponse { - transaction?: string; - price?: number; - tradeMint?: string; - side?: "long" | "short"; - collateralAmount?: number; - collateralMint?: string; - leverage?: number; - slippage?: number; - token?: string; -} diff --git a/src/langchain/agent/create_image.ts b/src/langchain/agent/create_image.ts index 5837732..441945d 100644 --- a/src/langchain/agent/create_image.ts +++ b/src/langchain/agent/create_image.ts @@ -1,12 +1,16 @@ -import { BaseSolanaTool } from "../common/base"; -import { CreateImageResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import { create_image } from "../../tools/agent"; -export class SolanaCreateImageTool extends BaseSolanaTool { +export class SolanaCreateImageTool extends Tool { name = "solana_create_image"; description = "Create an image using OpenAI's DALL-E. Input should be a string prompt for the image."; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + private validateInput(input: string): void { if (typeof input !== "string" || input.trim().length === 0) { throw new Error("Input must be a non-empty string prompt"); @@ -22,9 +26,13 @@ export class SolanaCreateImageTool extends BaseSolanaTool { status: "success", message: "Image created successfully", ...result, - } as CreateImageResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/agent/types.ts b/src/langchain/agent/types.ts deleted file mode 100644 index 8dce4d6..0000000 --- a/src/langchain/agent/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface CreateImageResponse extends BaseToolResponse { - images?: string[]; -} - -export interface WalletAddressResponse extends BaseToolResponse { - address?: string; -} diff --git a/src/langchain/agent/wallet_address.ts b/src/langchain/agent/wallet_address.ts index 79408fb..402f9f6 100644 --- a/src/langchain/agent/wallet_address.ts +++ b/src/langchain/agent/wallet_address.ts @@ -1,15 +1,15 @@ -import { BaseSolanaTool } from "../common/base"; -import { WalletAddressResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaGetWalletAddressTool extends BaseSolanaTool { +export class SolanaGetWalletAddressTool extends Tool { name = "solana_get_wallet_address"; - description = "Get the wallet address of the agent"; + description = `Get the wallet address of the agent`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } async _call(_input: string): Promise { - return JSON.stringify({ - status: "success", - message: "Wallet address retrieved successfully", - address: this.solanaKit.wallet_address.toString(), - } as WalletAddressResponse); + return this.solanaKit.wallet_address.toString(); } } diff --git a/src/langchain/bonfida/get_domain.ts b/src/langchain/bonfida/get_domain.ts index b81759e..6456879 100644 --- a/src/langchain/bonfida/get_domain.ts +++ b/src/langchain/bonfida/get_domain.ts @@ -1,13 +1,18 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { DomainResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaGetDomainTool extends BaseSolanaTool { +export class SolanaGetDomainTool extends Tool { name = "solana_get_domain"; description = `Retrieve the .sol domain associated for a given account address. Inputs: - account: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)`; + account: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -18,9 +23,13 @@ export class SolanaGetDomainTool extends BaseSolanaTool { status: "success", message: "Primary domain retrieved successfully", domain, - } as DomainResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/bonfida/main_domain.ts b/src/langchain/bonfida/main_domain.ts index d9df61c..4bd17e8 100644 --- a/src/langchain/bonfida/main_domain.ts +++ b/src/langchain/bonfida/main_domain.ts @@ -1,15 +1,19 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { DomainResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaGetMainDomain extends BaseSolanaTool { +export class SolanaGetMainDomain extends Tool { name = "solana_get_main_domain"; description = `Get the main/favorite domain for a given wallet address. Inputs: owner: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)`; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { const ownerPubkey = new PublicKey(input.trim()); const mainDomain = @@ -19,9 +23,13 @@ export class SolanaGetMainDomain extends BaseSolanaTool { status: "success", message: "Main domain fetched successfully", domain: mainDomain, - } as DomainResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_MAIN_DOMAIN_ERROR", + }); } } } diff --git a/src/langchain/bonfida/register_domain.ts b/src/langchain/bonfida/register_domain.ts index d4d3b94..d59d668 100644 --- a/src/langchain/bonfida/register_domain.ts +++ b/src/langchain/bonfida/register_domain.ts @@ -1,32 +1,54 @@ -import { BaseSolanaTool } from "../common/base"; -import { RegisterDomainInput, RegisterDomainResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRegisterDomainTool extends BaseSolanaTool { +export class SolanaRegisterDomainTool extends Tool { name = "solana_register_domain"; description = `Register a .sol domain name for your wallet. Inputs: name: string, eg "pumpfun.sol" (required) - spaceKB: number, eg 1 (optional, default is 1)`; + spaceKB: number, eg 1 (optional, default is 1) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + private validateInput(input: any): void { + if (!input.name || typeof input.name !== "string") { + throw new Error("name is required and must be a string"); + } + if ( + input.spaceKB !== undefined && + (typeof input.spaceKB !== "number" || input.spaceKB <= 0) + ) { + throw new Error("spaceKB must be a positive number when provided"); + } + } protected async _call(input: string): Promise { try { - const params: RegisterDomainInput = JSON.parse(input); + const parsedInput = JSON.parse(input); + this.validateInput(parsedInput); const tx = await this.solanaKit.registerDomain( - params.name, - params.spaceKB || 1, + parsedInput.name, + parsedInput.spaceKB || 1, ); return JSON.stringify({ status: "success", message: "Domain registered successfully", transaction: tx, - domain: `${params.name}.sol`, - spaceKB: params.spaceKB || 1, - } as RegisterDomainResponse); + domain: `${parsedInput.name}.sol`, + spaceKB: parsedInput.spaceKB || 1, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/bonfida/resolve_domain.ts b/src/langchain/bonfida/resolve_domain.ts index be3dd6d..77e71a6 100644 --- a/src/langchain/bonfida/resolve_domain.ts +++ b/src/langchain/bonfida/resolve_domain.ts @@ -1,14 +1,19 @@ -import { BaseSolanaTool } from "../common/base"; -import { ResolveDomainResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaResolveDomainTool extends BaseSolanaTool { +export class SolanaResolveDomainTool extends Tool { name = "solana_resolve_domain"; description = `Resolve ONLY .sol domain names to a Solana PublicKey. This tool is exclusively for .sol domains. DO NOT use this for other domain types like .blink, .bonk, etc. Inputs: - domain: string, eg "pumpfun.sol" (required)`; + domain: string, eg "pumpfun.sol" (required) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -19,9 +24,13 @@ export class SolanaResolveDomainTool extends BaseSolanaTool { status: "success", message: "Domain resolved successfully", publicKey: publicKey.toBase58(), - } as ResolveDomainResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/bonfida/types.ts b/src/langchain/bonfida/types.ts deleted file mode 100644 index bf9a31f..0000000 --- a/src/langchain/bonfida/types.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface RegisterDomainInput { - name: string; - spaceKB?: number; -} - -export interface ResolveDomainInput { - domain: string; -} - -export interface GetDomainInput { - account: string; -} - -export interface OwnedDomainsInput { - owner: string; -} - -export interface TldDomainsInput { - tld: string; -} - -export interface RegisterDomainResponse extends BaseToolResponse { - transaction?: string; - domain?: string; - spaceKB?: number; -} - -export interface ResolveDomainResponse extends BaseToolResponse { - publicKey?: string; - owner?: string; -} - -export interface DomainResponse extends BaseToolResponse { - domain?: string | null; -} - -export interface DomainsListResponse extends BaseToolResponse { - domains?: string[]; -} - -export interface TldsResponse extends BaseToolResponse { - tlds?: string[]; -} diff --git a/src/langchain/common/base.ts b/src/langchain/common/base.ts deleted file mode 100644 index 80757ca..0000000 --- a/src/langchain/common/base.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Tool } from "langchain/tools"; -import { SolanaAgentKit } from "../../agent"; -import { BaseToolResponse } from "./types"; - -export abstract class BaseSolanaTool extends Tool { - constructor(protected solanaKit: SolanaAgentKit) { - super(); - } - - protected handleError(error: any): string { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - } as BaseToolResponse); - } -} diff --git a/src/langchain/common/index.ts b/src/langchain/common/index.ts deleted file mode 100644 index 97fae0d..0000000 --- a/src/langchain/common/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./types"; -export * from "./base"; diff --git a/src/langchain/common/types.ts b/src/langchain/common/types.ts deleted file mode 100644 index 71400bb..0000000 --- a/src/langchain/common/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface BaseToolResponse { - status: "success" | "error"; - message: string; - code?: string; -} diff --git a/src/langchain/dexscreener/token_data_ticker.ts b/src/langchain/dexscreener/token_data_ticker.ts index 42df350..88d8a6d 100644 --- a/src/langchain/dexscreener/token_data_ticker.ts +++ b/src/langchain/dexscreener/token_data_ticker.ts @@ -1,23 +1,31 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaTokenDataByTickerTool extends BaseSolanaTool { +export class SolanaTokenDataByTickerTool extends Tool { name = "solana_token_data_by_ticker"; description = `Get the token data for a given token ticker Inputs: ticker is required. ticker: string, eg "USDC" (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const ticker = input.trim(); const tokenData = await this.solanaKit.getTokenDataByTicker(ticker); - return JSON.stringify({ status: "success", tokenData, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/flash/flash_close.ts b/src/langchain/flash/flash_close.ts index 623fd07..c671bb1 100644 --- a/src/langchain/flash/flash_close.ts +++ b/src/langchain/flash/flash_close.ts @@ -1,7 +1,7 @@ -import { BaseSolanaTool } from "../common/base"; -import { FlashCloseTradeInput, PerpTradeResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaFlashCloseTrade extends BaseSolanaTool { +export class SolanaFlashCloseTrade extends Tool { name = "solana_flash_close_trade"; description = `Close an existing leveraged trading position on Flash.Trade exchange. @@ -11,24 +11,43 @@ export class SolanaFlashCloseTrade extends BaseSolanaTool { Example prompt is Close a 20x leveraged trade for SOL on long side`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params: FlashCloseTradeInput = JSON.parse(input); + const parsedInput = JSON.parse(input); + + // Validate input parameters + if (!parsedInput.token) { + throw new Error("Token is required"); + } + if (!["SOL", "BTC", "ETH"].includes(parsedInput.token)) { + throw new Error('Token must be one of ["SOL", "BTC", "ETH"]'); + } + if (!["long", "short"].includes(parsedInput.side)) { + throw new Error('Side must be either "long" or "short"'); + } const tx = await this.solanaKit.flashCloseTrade({ - token: params.token, - side: params.side, + token: parsedInput.token, + side: parsedInput.side, }); return JSON.stringify({ status: "success", message: "Flash trade position closed successfully", transaction: tx, - token: params.token, - side: params.side, - } as PerpTradeResponse); + token: parsedInput.token, + side: parsedInput.side, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/flash/flash_open.ts b/src/langchain/flash/flash_open.ts index c8cdd0e..e35a966 100644 --- a/src/langchain/flash/flash_open.ts +++ b/src/langchain/flash/flash_open.ts @@ -1,7 +1,8 @@ -import { BaseSolanaTool } from "../common/base"; -import { FlashOpenTradeInput, PerpTradeResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { marketTokenMap } from "../../utils/flashUtils"; -export class SolanaFlashOpenTrade extends BaseSolanaTool { +export class SolanaFlashOpenTrade extends Tool { name = "solana_flash_open_trade"; description = `This tool can be used to open a new leveraged trading position on Flash.Trade exchange. @@ -13,28 +14,68 @@ export class SolanaFlashOpenTrade extends BaseSolanaTool { Example prompt is Open a 20x leveraged trade for SOL on long side using flash trade with 500 USD as collateral`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params: FlashOpenTradeInput = JSON.parse(input); + const parsedInput = JSON.parse(input); + + // Validate input parameters + if (!parsedInput.token) { + throw new Error("Token is required, received: " + parsedInput.token); + } + if (!Object.keys(marketTokenMap).includes(parsedInput.token)) { + throw new Error( + "Token must be one of " + + Object.keys(marketTokenMap).join(", ") + + ", received: " + + parsedInput.token + + "\n" + + "Please check https://beast.flash.trade/ for the list of supported tokens", + ); + } + if (!["long", "short"].includes(parsedInput.type)) { + throw new Error( + 'Type must be either "long" or "short", received: ' + + parsedInput.type, + ); + } + if (!parsedInput.collateral || parsedInput.collateral <= 0) { + throw new Error( + "Collateral amount must be positive, received: " + + parsedInput.collateral, + ); + } + if (!parsedInput.leverage || parsedInput.leverage <= 0) { + throw new Error( + "Leverage must be positive, received: " + parsedInput.leverage, + ); + } const tx = await this.solanaKit.flashOpenTrade({ - token: params.token, - side: params.type, - collateralUsd: params.collateral, - leverage: params.leverage, + token: parsedInput.token, + side: parsedInput.type, + collateralUsd: parsedInput.collateral, + leverage: parsedInput.leverage, }); return JSON.stringify({ status: "success", message: "Flash trade position opened successfully", transaction: tx, - token: params.token, - side: params.type, - collateralAmount: params.collateral, - leverage: params.leverage, - } as PerpTradeResponse); + token: parsedInput.token, + side: parsedInput.type, + collateral: parsedInput.collateral, + leverage: parsedInput.leverage, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/flash/index.ts b/src/langchain/flash/index.ts index bb17b16..da6243e 100644 --- a/src/langchain/flash/index.ts +++ b/src/langchain/flash/index.ts @@ -1,3 +1,2 @@ export * from "./flash_open"; export * from "./flash_close"; -export * from "./types"; diff --git a/src/langchain/flash/types.ts b/src/langchain/flash/types.ts deleted file mode 100644 index d733d5f..0000000 --- a/src/langchain/flash/types.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface FlashOpenTradeInput { - token: string; - type: "long" | "short"; - collateral: number; - leverage: number; -} - -export interface FlashCloseTradeInput { - token: string; - side: "long" | "short"; -} - -export interface PerpTradeResponse extends BaseToolResponse { - transaction?: string; - price?: number; - tradeMint?: string; - side?: "long" | "short"; - collateralAmount?: number; - collateralMint?: string; - leverage?: number; - slippage?: number; - token?: string; -} diff --git a/src/langchain/gibwork/create_task.ts b/src/langchain/gibwork/create_task.ts index e3a357e..c7af778 100644 --- a/src/langchain/gibwork/create_task.ts +++ b/src/langchain/gibwork/create_task.ts @@ -1,7 +1,8 @@ -import { BaseSolanaTool } from "../common/base"; -import { CreateGibworkTaskInput, GibworkTaskResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { GibworkCreateTaskReponse } from "../../index"; -export class SolanaCreateGibworkTask extends BaseSolanaTool { +export class SolanaCreateGibworkTask extends Tool { name = "create_gibwork_task"; description = `Create a task on Gibwork. @@ -12,30 +13,40 @@ export class SolanaCreateGibworkTask extends BaseSolanaTool { tags: string[], list of tags associated with the task (required) payer: string, payer address (optional, defaults to agent wallet) tokenMintAddress: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required) - amount: number, payment amount (required)`; + amount: number, payment amount (required) + `; + + constructor(private solanaSdk: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { - const params: CreateGibworkTaskInput = JSON.parse(input); + const parsedInput = JSON.parse(input); - const taskData = await this.solanaKit.createGibworkTask( - params.title, - params.content, - params.requirements, - params.tags, - params.tokenMintAddress, - params.amount, - params.payer, + const taskData = await this.solanaSdk.createGibworkTask( + parsedInput.title, + parsedInput.content, + parsedInput.requirements, + parsedInput.tags, + parsedInput.tokenMintAddress, + parsedInput.amount, + parsedInput.payer, ); - return JSON.stringify({ + const response: GibworkCreateTaskReponse = { status: "success", taskId: taskData.taskId, signature: taskData.signature, - message: `Task "${params.title}" created successfully`, - } as GibworkTaskResponse); - } catch (error: any) { - return this.handleError(error); + }; + + return JSON.stringify(response); + } catch (err: any) { + return JSON.stringify({ + status: "error", + message: err.message, + code: err.code || "CREATE_TASK_ERROR", + }); } } } diff --git a/src/langchain/gibwork/index.ts b/src/langchain/gibwork/index.ts index cbe7509..34d0b3b 100644 --- a/src/langchain/gibwork/index.ts +++ b/src/langchain/gibwork/index.ts @@ -1,2 +1 @@ export * from "./create_task"; -export * from "./types"; diff --git a/src/langchain/gibwork/types.ts b/src/langchain/gibwork/types.ts deleted file mode 100644 index 489ecbb..0000000 --- a/src/langchain/gibwork/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface CreateGibworkTaskInput { - title: string; - content: string; - requirements: string; - tags: string[]; - tokenMintAddress: string; - amount: number; - payer?: string; -} - -export interface GibworkTaskResponse extends BaseToolResponse { - taskId?: string; - signature?: string; -} diff --git a/src/langchain/index.ts b/src/langchain/index.ts index d0a3bb3..76efb18 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -56,9 +56,9 @@ import { SolanaBatchOrderTool, SolanaCancelAllOrdersTool, SolanaWithdrawAllTool, - SolanaOrcaClosePosition, + SolanaClosePosition, SolanaOrcaCreateCLMM, - SolanaOrcaCreateSingleSidedPool, + SolanaOrcaCreateSingleSideLiquidityPool, SolanaOrcaFetchPositions, SolanaOrcaOpenCenteredPosition, SolanaOrcaOpenSingleSidedPosition, @@ -117,9 +117,9 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaBatchOrderTool(solanaKit), new SolanaCancelAllOrdersTool(solanaKit), new SolanaWithdrawAllTool(solanaKit), - new SolanaOrcaClosePosition(solanaKit), + new SolanaClosePosition(solanaKit), new SolanaOrcaCreateCLMM(solanaKit), - new SolanaOrcaCreateSingleSidedPool(solanaKit), + new SolanaOrcaCreateSingleSideLiquidityPool(solanaKit), new SolanaOrcaFetchPositions(solanaKit), new SolanaOrcaOpenCenteredPosition(solanaKit), new SolanaOrcaOpenSingleSidedPosition(solanaKit), diff --git a/src/langchain/jupiter/fetch_price.ts b/src/langchain/jupiter/fetch_price.ts index 789625d..78df83b 100644 --- a/src/langchain/jupiter/fetch_price.ts +++ b/src/langchain/jupiter/fetch_price.ts @@ -1,13 +1,20 @@ -import { BaseSolanaTool } from "../common/base"; -import { PriceResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaFetchPriceTool extends BaseSolanaTool { +/** + * Tool to fetch the price of a token in USDC + */ +export class SolanaFetchPriceTool extends Tool { name = "solana_fetch_price"; description = `Fetch the price of a given token in USDC. Inputs: - tokenId: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { const price = await this.solanaKit.fetchTokenPrice(input.trim()); @@ -15,9 +22,13 @@ export class SolanaFetchPriceTool extends BaseSolanaTool { status: "success", tokenId: input.trim(), priceInUSDC: price, - } as PriceResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/jupiter/index.ts b/src/langchain/jupiter/index.ts index 2a09508..93b9b2a 100644 --- a/src/langchain/jupiter/index.ts +++ b/src/langchain/jupiter/index.ts @@ -2,4 +2,3 @@ export * from "./fetch_price"; export * from "./token_data"; export * from "./trade"; export * from "./stake"; -export * from "./types"; diff --git a/src/langchain/jupiter/stake.ts b/src/langchain/jupiter/stake.ts index 3c5d3fe..38a9263 100644 --- a/src/langchain/jupiter/stake.ts +++ b/src/langchain/jupiter/stake.ts @@ -1,13 +1,17 @@ -import { BaseSolanaTool } from "../common/base"; -import { StakeResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaStakeTool extends BaseSolanaTool { +export class SolanaStakeTool extends Tool { name = "solana_stake"; description = `This tool can be used to stake your SOL (Solana), also called as SOL staking or liquid staking. Inputs ( input is a JSON string ): amount: number, eg 1 or 0.01 (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const parsedInput = JSON.parse(input) || Number(input); @@ -19,9 +23,13 @@ export class SolanaStakeTool extends BaseSolanaTool { message: "Staked successfully", transaction: tx, amount: parsedInput.amount, - } as StakeResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/jupiter/token_data.ts b/src/langchain/jupiter/token_data.ts index 54fbc05..d202656 100644 --- a/src/langchain/jupiter/token_data.ts +++ b/src/langchain/jupiter/token_data.ts @@ -1,15 +1,21 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaTokenDataTool extends BaseSolanaTool { +export class SolanaTokenDataTool extends Tool { name = "solana_token_data"; description = `Get the token data for a given token mint address Inputs: mintAddress is required. mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const parsedInput = input.trim(); + const tokenData = await this.solanaKit.getTokenDataByAddress(parsedInput); return JSON.stringify({ @@ -17,7 +23,11 @@ export class SolanaTokenDataTool extends BaseSolanaTool { tokenData, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/jupiter/trade.ts b/src/langchain/jupiter/trade.ts index 9c88b5b..f3f03cc 100644 --- a/src/langchain/jupiter/trade.ts +++ b/src/langchain/jupiter/trade.ts @@ -1,15 +1,20 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import { PublicKey } from "@solana/web3.js"; -export class SolanaTradeTool extends BaseSolanaTool { +export class SolanaTradeTool extends Tool { name = "solana_trade"; description = `This tool can be used to swap tokens to another token ( It uses Jupiter Exchange ). - - Inputs ( input is a JSON string ): - outputMint: string, eg "So11111111111111111111111111111111111111112" or "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (required) - inputAmount: number, eg 1 or 0.01 (required) - inputMint?: string, eg "So11111111111111111111111111111111111111112" (optional) - slippageBps?: number, eg 100 (optional)`; + + Inputs ( input is a JSON string ): + outputMint: string, eg "So11111111111111111111111111111111111111112" or "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (required) + inputAmount: number, eg 1 or 0.01 (required) + inputMint?: string, eg "So11111111111111111111111111111111111111112" (optional) + slippageBps?: number, eg 100 (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -33,7 +38,11 @@ export class SolanaTradeTool extends BaseSolanaTool { outputToken: parsedInput.outputMint, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/jupiter/types.ts b/src/langchain/jupiter/types.ts deleted file mode 100644 index 42ca0e8..0000000 --- a/src/langchain/jupiter/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface FetchPriceInput { - tokenId: string; -} - -export interface PriceResponse extends BaseToolResponse { - tokenId?: string; - priceInUSDC?: string; -} - -export interface StakeInput { - amount: number; -} - -export interface StakeResponse extends BaseToolResponse { - transaction?: string; - amount?: number; -} diff --git a/src/langchain/lightprotocol/compressed_airdrop.ts b/src/langchain/lightprotocol/compressed_airdrop.ts index 0efa235..1cf5e8a 100644 --- a/src/langchain/lightprotocol/compressed_airdrop.ts +++ b/src/langchain/lightprotocol/compressed_airdrop.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaCompressedAirdropTool extends BaseSolanaTool { +export class SolanaCompressedAirdropTool extends Tool { name = "solana_compressed_airdrop"; description = `Airdrop SPL tokens with ZK Compression (also called as airdropping tokens) @@ -12,26 +13,34 @@ export class SolanaCompressedAirdropTool extends BaseSolanaTool { priorityFeeInLamports: number, the priority fee in lamports. Default is 30_000. (optional) shouldLog: boolean, whether to log progress to stdout. Default is false. (optional)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = JSON.parse(input); + const parsedInput = JSON.parse(input); const txs = await this.solanaKit.sendCompressedAirdrop( - params.mintAddress, - params.amount, - params.decimals, - params.recipients, - params.priorityFeeInLamports || 30_000, - params.shouldLog || false, + parsedInput.mintAddress, + parsedInput.amount, + parsedInput.decimals, + parsedInput.recipients, + parsedInput.priorityFeeInLamports || 30_000, + parsedInput.shouldLog || false, ); return JSON.stringify({ status: "success", - message: `Airdropped ${params.amount} tokens to ${params.recipients.length} recipients.`, + message: `Airdropped ${parsedInput.amount} tokens to ${parsedInput.recipients.length} recipients.`, transactionHashes: txs, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/lulo/index.ts b/src/langchain/lulo/index.ts index 9a7fe85..f4ecf39 100644 --- a/src/langchain/lulo/index.ts +++ b/src/langchain/lulo/index.ts @@ -1,2 +1 @@ export * from "./lend_asset"; -export * from "./types"; diff --git a/src/langchain/lulo/lend_asset.ts b/src/langchain/lulo/lend_asset.ts index c30300b..d1e2655 100644 --- a/src/langchain/lulo/lend_asset.ts +++ b/src/langchain/lulo/lend_asset.ts @@ -1,17 +1,20 @@ -import { BaseSolanaTool } from "../common/base"; -import { LendAssetResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaLendAssetTool extends BaseSolanaTool { +export class SolanaLendAssetTool extends Tool { name = "solana_lend_asset"; description = `Lend idle USDC for yield using Lulo. ( only USDC is supported ) Inputs (input is a json string): amount: number, eg 1, 0.01 (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { - // Parse input either as direct number or JSON object - const amount = JSON.parse(input).amount || Number(input); + const amount = JSON.parse(input).amount || input; const tx = await this.solanaKit.lendAssets(amount); @@ -20,9 +23,13 @@ export class SolanaLendAssetTool extends BaseSolanaTool { message: "Asset lent successfully", transaction: tx, amount, - } as LendAssetResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/lulo/types.ts b/src/langchain/lulo/types.ts deleted file mode 100644 index aba87b2..0000000 --- a/src/langchain/lulo/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface LendAssetInput { - amount: number; -} - -export interface LendAssetResponse extends BaseToolResponse { - transaction?: string; - amount?: number; -} diff --git a/src/langchain/manifest/batch_order.ts b/src/langchain/manifest/batch_order.ts index 4249efd..36dedbf 100644 --- a/src/langchain/manifest/batch_order.ts +++ b/src/langchain/manifest/batch_order.ts @@ -1,39 +1,44 @@ -import { BaseSolanaTool } from "../common"; import { OrderParams } from "../../types"; import { generateOrdersfromPattern } from "../../tools/manifest"; import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaBatchOrderTool extends BaseSolanaTool { +export class SolanaBatchOrderTool extends Tool { name = "solana_batch_order"; description = `Places multiple limit orders in one transaction using Manifest. Submit orders either as a list or pattern: - - 1. List format: - { - "marketId": "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ", - "orders": [ - { "quantity": 1, "side": "Buy", "price": 200 }, - { "quantity": 0.5, "side": "Sell", "price": 205 } - ] + + 1. List format: + { + "marketId": "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ", + "orders": [ + { "quantity": 1, "side": "Buy", "price": 200 }, + { "quantity": 0.5, "side": "Sell", "price": 205 } + ] + } + + 2. Pattern format: + { + "marketId": "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ", + "pattern": { + "side": "Buy", + "totalQuantity": 100, + "priceRange": { "max": 1.0 }, + "spacing": { "type": "percentage", "value": 1 }, + "numberOfOrders": 5 } - - 2. Pattern format: - { - "marketId": "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ", - "pattern": { - "side": "Buy", - "totalQuantity": 100, - "priceRange": { "max": 1.0 }, - "spacing": { "type": "percentage", "value": 1 }, - "numberOfOrders": 5 - } - } - - Examples: - - "Place 5 buy orders totaling 100 tokens, 1% apart below $1" - - "Create 3 sell orders of 10 tokens each between $50-$55" - - "Place buy orders worth 50 tokens, $0.10 spacing from $0.80" - - Important: All orders must be in one transaction. Combine buy and sell orders into a single pattern or list. Never break the orders down to individual buy or sell orders.`; + } + + Examples: + - "Place 5 buy orders totaling 100 tokens, 1% apart below $1" + - "Create 3 sell orders of 10 tokens each between $50-$55" + - "Place buy orders worth 50 tokens, $0.10 spacing from $0.80" + + Important: All orders must be in one transaction. Combine buy and sell orders into a single pattern or list. Never break the orders down to individual buy or sell orders.`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -82,7 +87,11 @@ export class SolanaBatchOrderTool extends BaseSolanaTool { orders: parsedInput.orders, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/manifest/cancel_orders.ts b/src/langchain/manifest/cancel_orders.ts index 1ef4ff3..4b185a9 100644 --- a/src/langchain/manifest/cancel_orders.ts +++ b/src/langchain/manifest/cancel_orders.ts @@ -1,12 +1,17 @@ -import { BaseSolanaTool } from "../common"; import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaCancelAllOrdersTool extends BaseSolanaTool { +export class SolanaCancelAllOrdersTool extends Tool { name = "solana_cancel_all_orders"; description = `This tool can be used to cancel all orders from a Manifest market. - - Input ( input is a JSON string ): - marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`; + + Input ( input is a JSON string ): + marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -20,7 +25,11 @@ export class SolanaCancelAllOrdersTool extends BaseSolanaTool { marketId, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/manifest/index.ts b/src/langchain/manifest/index.ts index f10156c..6657556 100644 --- a/src/langchain/manifest/index.ts +++ b/src/langchain/manifest/index.ts @@ -3,4 +3,3 @@ export * from "./batch_order"; export * from "./cancel_orders"; export * from "./limit_order"; export * from "./withdraw"; -export * from "./types"; diff --git a/src/langchain/manifest/limit_order.ts b/src/langchain/manifest/limit_order.ts index 73b23e1..72f26e5 100644 --- a/src/langchain/manifest/limit_order.ts +++ b/src/langchain/manifest/limit_order.ts @@ -1,17 +1,22 @@ -import { BaseSolanaTool } from "../common"; import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaLimitOrderTool extends BaseSolanaTool { +export class SolanaLimitOrderTool extends Tool { name = "solana_limit_order"; description = `This tool can be used to place limit orders using Manifest. - - Do not allow users to place multiple orders with this instruction, use solana_batch_order instead. - - Inputs ( input is a JSON string ): - marketId: PublicKey, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required) - quantity: number, eg 1 or 0.01 (required) - side: string, eg "Buy" or "Sell" (required) - price: number, in tokens eg 200 for SOL/USDC (required)`; + + Do not allow users to place multiple orders with this instruction, use solana_batch_order instead. + + Inputs ( input is a JSON string ): + marketId: PublicKey, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required) + quantity: number, eg 1 or 0.01 (required) + side: string, eg "Buy" or "Sell" (required) + price: number, in tokens eg 200 for SOL/USDC (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { @@ -34,7 +39,11 @@ export class SolanaLimitOrderTool extends BaseSolanaTool { price: parsedInput.price, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/manifest/manifest_market.ts b/src/langchain/manifest/manifest_market.ts index 0999f8d..d05bc70 100644 --- a/src/langchain/manifest/manifest_market.ts +++ b/src/langchain/manifest/manifest_market.ts @@ -1,22 +1,27 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { ManifestMarketInput, ManifestMarketResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaManifestCreateMarket extends BaseSolanaTool { +export class SolanaManifestCreateMarket extends Tool { name = "solana_manifest_create_market"; description = `Manifest market Inputs (input is a json string): baseMint: string (required) - quoteMint: string (required)`; + quoteMint: string (required) + `; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { - const params: ManifestMarketInput = JSON.parse(input); + const inputFormat = JSON.parse(input); const tx = await this.solanaKit.manifestCreateMarket( - new PublicKey(params.baseMint), - new PublicKey(params.quoteMint), + new PublicKey(inputFormat.baseMint), + new PublicKey(inputFormat.quoteMint), ); return JSON.stringify({ @@ -24,9 +29,13 @@ export class SolanaManifestCreateMarket extends BaseSolanaTool { message: "Create manifest market successfully", transaction: tx[0], marketId: tx[1], - } as ManifestMarketResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/manifest/types.ts b/src/langchain/manifest/types.ts deleted file mode 100644 index c0150f0..0000000 --- a/src/langchain/manifest/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface ManifestMarketInput { - baseMint: string; - quoteMint: string; -} - -export interface ManifestMarketResponse extends BaseToolResponse { - transaction: string; - marketId: string; -} diff --git a/src/langchain/manifest/withdraw.ts b/src/langchain/manifest/withdraw.ts index 7d110fb..31a172f 100644 --- a/src/langchain/manifest/withdraw.ts +++ b/src/langchain/manifest/withdraw.ts @@ -1,12 +1,17 @@ -import { BaseSolanaTool } from "../common"; import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaWithdrawAllTool extends BaseSolanaTool { +export class SolanaWithdrawAllTool extends Tool { name = "solana_withdraw_all"; description = `This tool can be used to withdraw all funds from a Manifest market. - - Input ( input is a JSON string ): - marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`; + + Input ( input is a JSON string ): + marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { diff --git a/src/langchain/metaplex/deploy_collection.ts b/src/langchain/metaplex/deploy_collection.ts index cd507a1..08f6d62 100644 --- a/src/langchain/metaplex/deploy_collection.ts +++ b/src/langchain/metaplex/deploy_collection.ts @@ -1,30 +1,37 @@ -import { BaseSolanaTool } from "../common/base"; -import { DeployCollectionInput, DeployCollectionResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaDeployCollectionTool extends BaseSolanaTool { +export class SolanaDeployCollectionTool extends Tool { name = "solana_deploy_collection"; description = `Deploy a new NFT collection on Solana blockchain. Inputs (input is a JSON string): name: string, eg "My Collection" (required) uri: string, eg "https://example.com/collection.json" (required) - royaltyBasisPoints?: number, eg 500 for 5% (optional) - creators?: Array of { address: string, percentage: number } (optional)`; + royaltyBasisPoints?: number, eg 500 for 5% (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { - const params: DeployCollectionInput = JSON.parse(input); + const parsedInput = JSON.parse(input); - const result = await this.solanaKit.deployCollection(params); + const result = await this.solanaKit.deployCollection(parsedInput); return JSON.stringify({ status: "success", message: "Collection deployed successfully", collectionAddress: result.collectionAddress.toString(), - name: params.name, - } as DeployCollectionResponse); + name: parsedInput.name, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/metaplex/deploy_token.ts b/src/langchain/metaplex/deploy_token.ts index 2b6454d..77eb692 100644 --- a/src/langchain/metaplex/deploy_token.ts +++ b/src/langchain/metaplex/deploy_token.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaDeployTokenTool extends BaseSolanaTool { +export class SolanaDeployTokenTool extends Tool { name = "solana_deploy_token"; description = `Deploy a new token on Solana blockchain. @@ -11,26 +12,34 @@ export class SolanaDeployTokenTool extends BaseSolanaTool { decimals?: number, eg 9 (optional, defaults to 9) initialSupply?: number, eg 1000000 (optional)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = JSON.parse(input); + const parsedInput = JSON.parse(input); const result = await this.solanaKit.deployToken( - params.name, - params.uri, - params.symbol, - params.decimals, - params.initialSupply, + parsedInput.name, + parsedInput.uri, + parsedInput.symbol, + parsedInput.decimals, + parsedInput.initialSupply, ); return JSON.stringify({ status: "success", message: "Token deployed successfully", mintAddress: result.mint.toString(), - decimals: params.decimals || 9, + decimals: parsedInput.decimals || 9, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/metaplex/index.ts b/src/langchain/metaplex/index.ts index f3aa4f4..7cdfe15 100644 --- a/src/langchain/metaplex/index.ts +++ b/src/langchain/metaplex/index.ts @@ -1,4 +1,3 @@ export * from "./deploy_collection"; export * from "./mint_nft"; export * from "./deploy_token"; -export * from "./types"; diff --git a/src/langchain/metaplex/mint_nft.ts b/src/langchain/metaplex/mint_nft.ts index 2acd5b9..775c6a4 100644 --- a/src/langchain/metaplex/mint_nft.ts +++ b/src/langchain/metaplex/mint_nft.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { MintNFTInput, MintNFTResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaMintNFTTool extends BaseSolanaTool { +export class SolanaMintNFTTool extends Tool { name = "solana_mint_nft"; description = `Mint a new NFT in a collection on Solana blockchain. @@ -10,20 +10,24 @@ export class SolanaMintNFTTool extends BaseSolanaTool { collectionMint: string, eg "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" (required) - The address of the collection to mint into name: string, eg "My NFT" (required) uri: string, eg "https://example.com/nft.json" (required) - recipient?: string, eg "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u" (optional) - The wallet to receive the NFT, defaults to agent's wallet`; + recipient?: string, eg "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u" (optional) - The wallet to receive the NFT, defaults to agent's wallet which is ${this.solanaKit.wallet_address.toString()}`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } protected async _call(input: string): Promise { try { - const params: MintNFTInput = JSON.parse(input); + const parsedInput = JSON.parse(input); const result = await this.solanaKit.mintNFT( - new PublicKey(params.collectionMint), + new PublicKey(parsedInput.collectionMint), { - name: params.name, - uri: params.uri, + name: parsedInput.name, + uri: parsedInput.uri, }, - params.recipient - ? new PublicKey(params.recipient) + parsedInput.recipient + ? new PublicKey(parsedInput.recipient) : this.solanaKit.wallet_address, ); @@ -32,13 +36,18 @@ export class SolanaMintNFTTool extends BaseSolanaTool { message: "NFT minted successfully", mintAddress: result.mint.toString(), metadata: { - name: params.name, - uri: params.uri, + name: parsedInput.name, + symbol: parsedInput.symbol, + uri: parsedInput.uri, }, - recipient: params.recipient || result.mint.toString(), - } as MintNFTResponse); + recipient: parsedInput.recipient || result.mint.toString(), + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/metaplex/types.ts b/src/langchain/metaplex/types.ts deleted file mode 100644 index ecfcafd..0000000 --- a/src/langchain/metaplex/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface DeployCollectionInput { - name: string; - uri: string; - royaltyBasisPoints?: number; - creators?: Array<{ - address: string; - percentage: number; - }>; -} - -export interface MintNFTInput { - collectionMint: string; - name: string; - uri: string; - recipient?: string; -} - -export interface DeployCollectionResponse extends BaseToolResponse { - collectionAddress?: string; - name?: string; -} - -export interface MintNFTResponse extends BaseToolResponse { - mintAddress?: string; - metadata?: { - name: string; - symbol?: string; - uri: string; - }; - recipient?: string; -} diff --git a/src/langchain/onsol/get_all_tld.ts b/src/langchain/onsol/get_all_tld.ts index 8f5f1b4..b6ee67c 100644 --- a/src/langchain/onsol/get_all_tld.ts +++ b/src/langchain/onsol/get_all_tld.ts @@ -1,9 +1,14 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaGetAllTlds extends BaseSolanaTool { +export class SolanaGetAllTlds extends Tool { name = "solana_get_all_tlds"; description = `Get all active top-level domains (TLDs) in the AllDomains Name Service`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(): Promise { try { const tlds = await this.solanaKit.getAllDomainsTLDs(); diff --git a/src/langchain/onsol/index.ts b/src/langchain/onsol/index.ts index 3149d75..f9f025c 100644 --- a/src/langchain/onsol/index.ts +++ b/src/langchain/onsol/index.ts @@ -2,4 +2,3 @@ export * from "./resolve_all_domains"; export * from "./owned_domains"; export * from "./tld_domains"; export * from "./get_all_tld"; -export * from "./types"; diff --git a/src/langchain/onsol/owned_domains.ts b/src/langchain/onsol/owned_domains.ts index dd5a3ca..df7e84d 100644 --- a/src/langchain/onsol/owned_domains.ts +++ b/src/langchain/onsol/owned_domains.ts @@ -1,15 +1,19 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { DomainsListResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaGetOwnedDomains extends BaseSolanaTool { +export class SolanaGetOwnedDomains extends Tool { name = "solana_get_owned_domains"; description = `Get all domains owned by a specific wallet address. Inputs: owner: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)`; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { const ownerPubkey = new PublicKey(input.trim()); const domains = await this.solanaKit.getOwnedAllDomains(ownerPubkey); @@ -18,9 +22,13 @@ export class SolanaGetOwnedDomains extends BaseSolanaTool { status: "success", message: "Owned domains fetched successfully", domains, - } as DomainsListResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_OWNED_DOMAINS_ERROR", + }); } } } diff --git a/src/langchain/onsol/resolve_all_domains.ts b/src/langchain/onsol/resolve_all_domains.ts index 586a7e2..30e053c 100644 --- a/src/langchain/onsol/resolve_all_domains.ts +++ b/src/langchain/onsol/resolve_all_domains.ts @@ -1,7 +1,7 @@ -import { BaseSolanaTool } from "../common/base"; -import { ResolveDomainResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaResolveAllDomainsTool extends BaseSolanaTool { +export class SolanaResolveAllDomainsTool extends Tool { name = "solana_resolve_all_domains"; description = `Resolve domain names to a public key for ALL domain types EXCEPT .sol domains. Use this for domains like .blink, .bonk, etc. @@ -10,7 +10,11 @@ export class SolanaResolveAllDomainsTool extends BaseSolanaTool { Input: domain: string, eg "mydomain.blink" or "mydomain.bonk" (required)`; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { const owner = await this.solanaKit.resolveAllDomains(input); @@ -19,16 +23,20 @@ export class SolanaResolveAllDomainsTool extends BaseSolanaTool { status: "error", message: "Domain not found", code: "DOMAIN_NOT_FOUND", - } as ResolveDomainResponse); + }); } return JSON.stringify({ status: "success", message: "Domain resolved successfully", owner: owner?.toString(), - } as ResolveDomainResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "DOMAIN_RESOLUTION_ERROR", + }); } } } diff --git a/src/langchain/onsol/tld_domains.ts b/src/langchain/onsol/tld_domains.ts index 7b09d1b..b3707dd 100644 --- a/src/langchain/onsol/tld_domains.ts +++ b/src/langchain/onsol/tld_domains.ts @@ -1,14 +1,18 @@ -import { BaseSolanaTool } from "../common/base"; -import { DomainsListResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaGetOwnedTldDomains extends BaseSolanaTool { +export class SolanaGetOwnedTldDomains extends Tool { name = "solana_get_owned_tld_domains"; description = `Get all domains owned by the agent's wallet for a specific TLD. Inputs: tld: string, eg "bonk" (required)`; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { const domains = await this.solanaKit.getOwnedDomainsForTLD(input); @@ -16,9 +20,13 @@ export class SolanaGetOwnedTldDomains extends BaseSolanaTool { status: "success", message: "TLD domains fetched successfully", domains, - } as DomainsListResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TLD_DOMAINS_ERROR", + }); } } } diff --git a/src/langchain/onsol/types.ts b/src/langchain/onsol/types.ts deleted file mode 100644 index bf9a31f..0000000 --- a/src/langchain/onsol/types.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface RegisterDomainInput { - name: string; - spaceKB?: number; -} - -export interface ResolveDomainInput { - domain: string; -} - -export interface GetDomainInput { - account: string; -} - -export interface OwnedDomainsInput { - owner: string; -} - -export interface TldDomainsInput { - tld: string; -} - -export interface RegisterDomainResponse extends BaseToolResponse { - transaction?: string; - domain?: string; - spaceKB?: number; -} - -export interface ResolveDomainResponse extends BaseToolResponse { - publicKey?: string; - owner?: string; -} - -export interface DomainResponse extends BaseToolResponse { - domain?: string | null; -} - -export interface DomainsListResponse extends BaseToolResponse { - domains?: string[]; -} - -export interface TldsResponse extends BaseToolResponse { - tlds?: string[]; -} diff --git a/src/langchain/openbook/index.ts b/src/langchain/openbook/index.ts index ef007ed..22b2ef1 100644 --- a/src/langchain/openbook/index.ts +++ b/src/langchain/openbook/index.ts @@ -1,2 +1 @@ export * from "./openbook_market"; -export * from "./types"; diff --git a/src/langchain/openbook/openbook_market.ts b/src/langchain/openbook/openbook_market.ts index e52b928..4f6b63c 100644 --- a/src/langchain/openbook/openbook_market.ts +++ b/src/langchain/openbook/openbook_market.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { OpenbookMarketInput } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOpenbookCreateMarket extends BaseSolanaTool { +export class SolanaOpenbookCreateMarket extends Tool { name = "solana_openbook_create_market"; description = `Openbook marketId, required for ammv4 @@ -10,17 +10,23 @@ export class SolanaOpenbookCreateMarket extends BaseSolanaTool { baseMint: string (required) quoteMint: string (required) lotSize: number (required) - tickSize: number (required)`; + tickSize: number (required) + `; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { - const params: OpenbookMarketInput = JSON.parse(input); + const inputFormat = JSON.parse(input); const tx = await this.solanaKit.openbookCreateMarket( - new PublicKey(params.baseMint), - new PublicKey(params.quoteMint), - params.lotSize, - params.tickSize, + new PublicKey(inputFormat.baseMint), + new PublicKey(inputFormat.quoteMint), + + inputFormat.lotSize, + inputFormat.tickSize, ); return JSON.stringify({ @@ -29,7 +35,11 @@ export class SolanaOpenbookCreateMarket extends BaseSolanaTool { transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/openbook/types.ts b/src/langchain/openbook/types.ts deleted file mode 100644 index 6ae5503..0000000 --- a/src/langchain/openbook/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface OpenbookMarketInput { - baseMint: string; - quoteMint: string; - lotSize: number; - tickSize: number; -} diff --git a/src/langchain/orca/index.ts b/src/langchain/orca/index.ts index f3011c2..10358af 100644 --- a/src/langchain/orca/index.ts +++ b/src/langchain/orca/index.ts @@ -4,4 +4,3 @@ export * from "./orca_position"; export * from "./orca_fetch_positions"; export * from "./orca_centered_position"; export * from "./orca_single_sided_position"; -export * from "./types"; diff --git a/src/langchain/orca/orca_centered_position.ts b/src/langchain/orca/orca_centered_position.ts index cb4df17..ca7abca 100644 --- a/src/langchain/orca/orca_centered_position.ts +++ b/src/langchain/orca/orca_centered_position.ts @@ -1,9 +1,9 @@ import { PublicKey } from "@solana/web3.js"; import { Decimal } from "decimal.js"; -import { BaseSolanaTool } from "../common/base"; -import { OrcaCenteredPositionInput, LiquidityResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOrcaOpenCenteredPosition extends BaseSolanaTool { +export class SolanaOrcaOpenCenteredPosition extends Tool { name = "orca_open_centered_position_with_liquidity"; description = `Add liquidity to a CLMM by opening a centered position in an Orca Whirlpool, the most efficient liquidity pool on Solana. @@ -13,23 +13,42 @@ export class SolanaOrcaOpenCenteredPosition extends BaseSolanaTool { - inputTokenMint: string, mint address of the deposit token (required). - inputAmount: number, amount of the deposit token, e.g., 100.0 (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { - const params: OrcaCenteredPositionInput = JSON.parse(input); + const inputFormat = JSON.parse(input); + const whirlpoolAddress = new PublicKey(inputFormat.whirlpoolAddress); + const priceOffsetBps = parseInt(inputFormat.priceOffsetBps, 10); + const inputTokenMint = new PublicKey(inputFormat.inputTokenMint); + const inputAmount = new Decimal(inputFormat.inputAmount); + + if (priceOffsetBps < 0) { + throw new Error( + "Invalid distanceFromCurrentPriceBps. It must be equal or greater than 0.", + ); + } + const txId = await this.solanaKit.orcaOpenCenteredPositionWithLiquidity( - new PublicKey(params.whirlpoolAddress), - params.priceOffsetBps, - new PublicKey(params.inputTokenMint), - new Decimal(params.inputAmount), + whirlpoolAddress, + priceOffsetBps, + inputTokenMint, + inputAmount, ); return JSON.stringify({ status: "success", message: "Centered liquidity position opened successfully.", transaction: txId, - } as LiquidityResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/orca/orca_clmm.ts b/src/langchain/orca/orca_clmm.ts index 609a9de..8508a45 100644 --- a/src/langchain/orca/orca_clmm.ts +++ b/src/langchain/orca/orca_clmm.ts @@ -1,10 +1,10 @@ import { PublicKey } from "@solana/web3.js"; import { Decimal } from "decimal.js"; -import { BaseSolanaTool } from "../common/base"; -import { LiquidityResponse } from "./types"; import { FEE_TIERS } from "../../tools/orca"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOrcaCreateCLMM extends BaseSolanaTool { +export class SolanaOrcaCreateCLMM extends Tool { name = "orca_create_clmm"; description = `Create a Concentrated Liquidity Market Maker (CLMM) pool on Orca, the most efficient and capital-optimized CLMM on Solana. This function initializes a CLMM pool but does not add liquidity. You can add liquidity later using a centered position or a single-sided position. @@ -14,10 +14,17 @@ export class SolanaOrcaCreateCLMM extends BaseSolanaTool { - initialPrice: number, initial price of mintA in terms of mintB, e.g., 0.001 (required). - feeTier: number, fee tier in bps. Options: 1, 2, 4, 5, 16, 30, 65, 100, 200 (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { - const params = JSON.parse(input); - const feeTier = params.feeTier; + const inputFormat = JSON.parse(input); + const mintA = new PublicKey(inputFormat.mintDeploy); + const mintB = new PublicKey(inputFormat.mintPair); + const initialPrice = new Decimal(inputFormat.initialPrice); + const feeTier = inputFormat.feeTier; if (!feeTier || !(feeTier in FEE_TIERS)) { throw new Error( @@ -26,10 +33,11 @@ export class SolanaOrcaCreateCLMM extends BaseSolanaTool { )}`, ); } + const txId = await this.solanaKit.orcaCreateCLMM( - new PublicKey(params.mintDeploy), - new PublicKey(params.mintPair), - new Decimal(params.initialPrice), + mintA, + mintB, + initialPrice, feeTier, ); @@ -38,9 +46,13 @@ export class SolanaOrcaCreateCLMM extends BaseSolanaTool { message: "CLMM pool created successfully. Note: No liquidity was added.", transaction: txId, - } as LiquidityResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/orca/orca_fetch_positions.ts b/src/langchain/orca/orca_fetch_positions.ts index 591e2a6..820780b 100644 --- a/src/langchain/orca/orca_fetch_positions.ts +++ b/src/langchain/orca/orca_fetch_positions.ts @@ -1,21 +1,29 @@ -import { BaseSolanaTool } from "../common/base"; -import { OrcaPositionsResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOrcaFetchPositions extends BaseSolanaTool { +export class SolanaOrcaFetchPositions extends Tool { name = "orca_fetch_positions"; - description = `Fetch all the liquidity positions in an Orca Whirlpool by owner. Returns an object with position mint addresses as keys and position status details as values.`; + description = `Fetch all the liquidity positions in an Orca Whirlpool by owner. Returns an object with positiont mint addresses as keys and position status details as values.`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } async _call(): Promise { try { - const positions = await this.solanaKit.orcaFetchPositions(); + const txId = await this.solanaKit.orcaFetchPositions(); return JSON.stringify({ status: "success", - message: "Liquidity positions fetched successfully", - positions: JSON.parse(positions), - } as OrcaPositionsResponse); + message: "Liquidity positions fetched.", + transaction: txId, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/orca/orca_position.ts b/src/langchain/orca/orca_position.ts index d001e5c..a72ecc2 100644 --- a/src/langchain/orca/orca_position.ts +++ b/src/langchain/orca/orca_position.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { OrcaPositionInput, LiquidityResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOrcaClosePosition extends BaseSolanaTool { +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. @@ -10,20 +10,30 @@ export class SolanaOrcaClosePosition extends BaseSolanaTool { Inputs (JSON string): - positionMintAddress: string, the address of the position mint that represents the liquidity position.`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { - const params: OrcaPositionInput = JSON.parse(input); - const txId = await this.solanaKit.orcaClosePosition( - new PublicKey(params.positionMintAddress), + const inputFormat = JSON.parse(input); + const positionMintAddress = new PublicKey( + inputFormat.positionMintAddress, ); + const txId = await this.solanaKit.orcaClosePosition(positionMintAddress); + return JSON.stringify({ status: "success", message: "Liquidity position closed successfully.", transaction: txId, - } as LiquidityResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/orca/orca_single_sided_pool.ts b/src/langchain/orca/orca_single_sided_pool.ts index bd0dbf4..549373b 100644 --- a/src/langchain/orca/orca_single_sided_pool.ts +++ b/src/langchain/orca/orca_single_sided_pool.ts @@ -1,10 +1,10 @@ import { PublicKey } from "@solana/web3.js"; import { Decimal } from "decimal.js"; -import { BaseSolanaTool } from "../common/base"; -import { LiquidityResponse } from "./types"; import { FEE_TIERS } from "../../tools/orca"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOrcaCreateSingleSidedPool extends BaseSolanaTool { +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. @@ -18,10 +18,19 @@ export class SolanaOrcaCreateSingleSidedPool extends BaseSolanaTool { - maxPrice: number, maximum price at which liquidity is added, e.g., 5.0 (required). - feeTier: number, fee tier for the pool in bps. Options: 1, 2, 4, 5, 16, 30, 65, 100, 200 (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { - const params = JSON.parse(input); - const feeTier = params.feeTier; + const inputFormat = JSON.parse(input); + const depositTokenAmount = inputFormat.depositTokenAmount; + const depositTokenMint = new PublicKey(inputFormat.depositTokenMint); + const otherTokenMint = new PublicKey(inputFormat.otherTokenMint); + const initialPrice = new Decimal(inputFormat.initialPrice); + const maxPrice = new Decimal(inputFormat.maxPrice); + const feeTier = inputFormat.feeTier; if (!feeTier || !(feeTier in FEE_TIERS)) { throw new Error( @@ -30,12 +39,13 @@ export class SolanaOrcaCreateSingleSidedPool extends BaseSolanaTool { )}`, ); } + const txId = await this.solanaKit.orcaCreateSingleSidedLiquidityPool( - params.depositTokenAmount, - new PublicKey(params.depositTokenMint), - new PublicKey(params.otherTokenMint), - new Decimal(params.initialPrice), - new Decimal(params.maxPrice), + depositTokenAmount, + depositTokenMint, + otherTokenMint, + initialPrice, + maxPrice, feeTier, ); @@ -43,9 +53,13 @@ export class SolanaOrcaCreateSingleSidedPool extends BaseSolanaTool { status: "success", message: "Single-sided Whirlpool created successfully", transaction: txId, - } as LiquidityResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/orca/orca_single_sided_position.ts b/src/langchain/orca/orca_single_sided_position.ts index 47f5a0d..d7b993e 100644 --- a/src/langchain/orca/orca_single_sided_position.ts +++ b/src/langchain/orca/orca_single_sided_position.ts @@ -1,37 +1,58 @@ import { PublicKey } from "@solana/web3.js"; import { Decimal } from "decimal.js"; -import { BaseSolanaTool } from "../common/base"; -import { OrcaSingleSidedPositionInput, LiquidityResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaOrcaOpenSingleSidedPosition extends BaseSolanaTool { +export class SolanaOrcaOpenSingleSidedPosition extends Tool { name = "orca_open_single_sided_position"; description = `Add liquidity to a CLMM by opening a single-sided position in an Orca Whirlpool, the most efficient liquidity pool on Solana. Inputs (JSON string): - whirlpoolAddress: string, address of the Orca Whirlpool (required). - - distanceFromCurrentPriceBps: number, distance in basis points from the current price (required). + - distanceFromCurrentPriceBps: number, distance in basis points from the current price for the position (required). - widthBps: number, width of the position in basis points (required). - inputTokenMint: string, mint address of the deposit token (required). - inputAmount: number, amount of the deposit token, e.g., 100.0 (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { - const params: OrcaSingleSidedPositionInput = JSON.parse(input); + const inputFormat = JSON.parse(input); + const whirlpoolAddress = new PublicKey(inputFormat.whirlpoolAddress); + const distanceFromCurrentPriceBps = + inputFormat.distanceFromCurrentPriceBps; + const widthBps = inputFormat.widthBps; + const inputTokenMint = new PublicKey(inputFormat.inputTokenMint); + const inputAmount = new Decimal(inputFormat.inputAmount); + + if (distanceFromCurrentPriceBps < 0 || widthBps < 0) { + throw new Error( + "Invalid distanceFromCurrentPriceBps or width. It must be equal or greater than 0.", + ); + } + const txId = await this.solanaKit.orcaOpenSingleSidedPosition( - new PublicKey(params.whirlpoolAddress), - params.distanceFromCurrentPriceBps, - params.widthBps, - new PublicKey(params.inputTokenMint), - new Decimal(params.inputAmount), + whirlpoolAddress, + distanceFromCurrentPriceBps, + widthBps, + inputTokenMint, + inputAmount, ); return JSON.stringify({ status: "success", message: "Single-sided liquidity position opened successfully.", transaction: txId, - } as LiquidityResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/orca/types.ts b/src/langchain/orca/types.ts deleted file mode 100644 index a7e51dc..0000000 --- a/src/langchain/orca/types.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface OrcaClmmInput { - mintDeploy: string; - mintPair: string; - initialPrice: number | string; - feeTier: string; -} - -export interface OrcaSingleSidedInput { - depositTokenAmount: number; - depositTokenMint: string; - otherTokenMint: string; - initialPrice: number | string; - maxPrice: number | string; - feeTier: string; -} - -export interface OrcaPositionInput { - positionMintAddress: string; -} - -export interface OrcaCenteredPositionInput { - whirlpoolAddress: string; - priceOffsetBps: number; - inputTokenMint: string; - inputAmount: number | string; -} - -export interface OrcaSingleSidedPositionInput { - whirlpoolAddress: string; - distanceFromCurrentPriceBps: number; - widthBps: number; - inputTokenMint: string; - inputAmount: number | string; -} - -export interface LiquidityResponse extends BaseToolResponse { - transaction?: string; -} - -export interface OrcaPositionsResponse extends BaseToolResponse { - positions?: Record< - string, - { - whirlpoolAddress: string; - positionInRange: boolean; - distanceFromCenterBps: number; - } - >; -} diff --git a/src/langchain/pumpfun/launch_pumpfun_token.ts b/src/langchain/pumpfun/launch_pumpfun_token.ts index a4df4ba..6fbabcf 100644 --- a/src/langchain/pumpfun/launch_pumpfun_token.ts +++ b/src/langchain/pumpfun/launch_pumpfun_token.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaPumpfunTokenLaunchTool extends BaseSolanaTool { +export class SolanaPumpfunTokenLaunchTool extends Tool { name = "solana_launch_pumpfun_token"; description = `This tool can be used to launch a token on Pump.fun, @@ -14,6 +15,10 @@ export class SolanaPumpfunTokenLaunchTool extends BaseSolanaTool { description: string, eg "PumpFun Token is a token on the Solana blockchain", imageUrl: string, eg "https://i.imgur.com/UFm07Np_d.png`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + private validateInput(input: any): void { if (!input.tokenName || typeof input.tokenName !== "string") { throw new Error("tokenName is required and must be a string"); diff --git a/src/langchain/pyth/index.ts b/src/langchain/pyth/index.ts index fe2e481..5cf3952 100644 --- a/src/langchain/pyth/index.ts +++ b/src/langchain/pyth/index.ts @@ -1,2 +1 @@ export * from "./pyth_price"; -export * from "./types"; diff --git a/src/langchain/pyth/pyth_price.ts b/src/langchain/pyth/pyth_price.ts index 615af3b..0ac524c 100644 --- a/src/langchain/pyth/pyth_price.ts +++ b/src/langchain/pyth/pyth_price.ts @@ -1,19 +1,24 @@ -import { BaseSolanaTool } from "../common/base"; -import { PythPriceResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PythFetchPriceResponse } from "../../index"; -export class SolanaPythFetchPrice extends BaseSolanaTool { +export class SolanaPythFetchPrice extends Tool { name = "solana_pyth_fetch_price"; description = `Fetch the price of a given price feed from Pyth's Hermes service Inputs: tokenSymbol: string, e.g., BTC for bitcoin`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { try { const priceFeedID = await this.solanaKit.getPythPriceFeedID(input); const price = await this.solanaKit.getPythPrice(priceFeedID); - const response = { + const response: PythFetchPriceResponse = { status: "success", tokenSymbol: input, priceFeedID, @@ -22,7 +27,7 @@ export class SolanaPythFetchPrice extends BaseSolanaTool { return JSON.stringify(response); } catch (error: any) { - const response: PythPriceResponse = { + const response: PythFetchPriceResponse = { status: "error", tokenSymbol: input, message: error.message, diff --git a/src/langchain/pyth/types.ts b/src/langchain/pyth/types.ts deleted file mode 100644 index 8e31745..0000000 --- a/src/langchain/pyth/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface PythFetchPriceInput { - tokenSymbol: string; -} - -export interface PythPriceResponse extends BaseToolResponse { - tokenSymbol?: string; - priceFeedID?: string; - price?: string; -} diff --git a/src/langchain/raydium/raydium_amm.ts b/src/langchain/raydium/raydium_amm.ts index 898b242..f31858a 100644 --- a/src/langchain/raydium/raydium_amm.ts +++ b/src/langchain/raydium/raydium_amm.ts @@ -1,9 +1,9 @@ import { PublicKey } from "@solana/web3.js"; import { BN } from "@coral-xyz/anchor"; -import { BaseSolanaTool } from "../common/base"; -import { RaydiumAmmV4Input } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRaydiumCreateAmmV4 extends BaseSolanaTool { +export class SolanaRaydiumCreateAmmV4 extends Tool { name = "raydium_create_ammV4"; description = `Raydium's Legacy AMM that requires an OpenBook marketID @@ -11,17 +11,22 @@ export class SolanaRaydiumCreateAmmV4 extends BaseSolanaTool { marketId: string (required) baseAmount: number(int), eg: 111111 (required) quoteAmount: number(int), eg: 111111 (required) - startTime: number(seconds), eg: now number or zero (required)`; + startTime: number(seconds), eg: now number or zero (required) + `; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { - const params: RaydiumAmmV4Input = JSON.parse(input); + const inputFormat = JSON.parse(input); const tx = await this.solanaKit.raydiumCreateAmmV4( - new PublicKey(params.marketId), - new BN(params.baseAmount), - new BN(params.quoteAmount), - new BN(params.startTime), + new PublicKey(inputFormat.marketId), + new BN(inputFormat.baseAmount), + new BN(inputFormat.quoteAmount), + new BN(inputFormat.startTime), ); return JSON.stringify({ @@ -30,7 +35,11 @@ export class SolanaRaydiumCreateAmmV4 extends BaseSolanaTool { transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/raydium/raydium_clmm.ts b/src/langchain/raydium/raydium_clmm.ts index 4e6de08..9d493e5 100644 --- a/src/langchain/raydium/raydium_clmm.ts +++ b/src/langchain/raydium/raydium_clmm.ts @@ -1,10 +1,10 @@ import { PublicKey } from "@solana/web3.js"; import { BN } from "@coral-xyz/anchor"; import { Decimal } from "decimal.js"; -import { BaseSolanaTool } from "../common/base"; -import { RaydiumClmmInput } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRaydiumCreateClmm extends BaseSolanaTool { +export class SolanaRaydiumCreateClmm extends Tool { name = "raydium_create_clmm"; description = `Concentrated liquidity market maker, custom liquidity ranges, increased capital efficiency @@ -13,18 +13,25 @@ export class SolanaRaydiumCreateClmm extends BaseSolanaTool { mint2: string (required) configId: string (required) stores pool info, id, index, protocolFeeRate, tradeFeeRate, tickSpacing, fundFeeRate initialPrice: number, eg: 123.12 (required) - startTime: number(seconds), eg: now number or zero (required)`; + startTime: number(seconds), eg: now number or zero (required) + `; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { - const params: RaydiumClmmInput = JSON.parse(input); + const inputFormat = JSON.parse(input); const tx = await this.solanaKit.raydiumCreateClmm( - new PublicKey(params.mint1), - new PublicKey(params.mint2), - new PublicKey(params.configId), - new Decimal(params.initialPrice), - new BN(params.startTime), + new PublicKey(inputFormat.mint1), + new PublicKey(inputFormat.mint2), + + new PublicKey(inputFormat.configId), + + new Decimal(inputFormat.initialPrice), + new BN(inputFormat.startTime), ); return JSON.stringify({ @@ -33,7 +40,11 @@ export class SolanaRaydiumCreateClmm extends BaseSolanaTool { transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/raydium/raydium_cpmm.ts b/src/langchain/raydium/raydium_cpmm.ts index aeb6284..81ded50 100644 --- a/src/langchain/raydium/raydium_cpmm.ts +++ b/src/langchain/raydium/raydium_cpmm.ts @@ -1,9 +1,9 @@ import { PublicKey } from "@solana/web3.js"; import { BN } from "@coral-xyz/anchor"; -import { BaseSolanaTool } from "../common/base"; -import { RaydiumCpmmInput } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRaydiumCreateCpmm extends BaseSolanaTool { +export class SolanaRaydiumCreateCpmm extends Tool { name = "raydium_create_cpmm"; description = `Raydium's newest CPMM, does not require marketID, supports Token 2022 standard @@ -13,19 +13,27 @@ export class SolanaRaydiumCreateCpmm extends BaseSolanaTool { configId: string (required), stores pool info, index, protocolFeeRate, tradeFeeRate, fundFeeRate, createPoolFee mintAAmount: number(int), eg: 1111 (required) mintBAmount: number(int), eg: 2222 (required) - startTime: number(seconds), eg: now number or zero (required)`; + startTime: number(seconds), eg: now number or zero (required) + `; - protected async _call(input: string): Promise { + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { try { - const params: RaydiumCpmmInput = JSON.parse(input); + const inputFormat = JSON.parse(input); const tx = await this.solanaKit.raydiumCreateCpmm( - new PublicKey(params.mint1), - new PublicKey(params.mint2), - new PublicKey(params.configId), - new BN(params.mintAAmount), - new BN(params.mintBAmount), - new BN(params.startTime), + new PublicKey(inputFormat.mint1), + new PublicKey(inputFormat.mint2), + + new PublicKey(inputFormat.configId), + + new BN(inputFormat.mintAAmount), + new BN(inputFormat.mintBAmount), + + new BN(inputFormat.startTime), ); return JSON.stringify({ @@ -34,7 +42,11 @@ export class SolanaRaydiumCreateCpmm extends BaseSolanaTool { transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/rugcheck/index.ts b/src/langchain/rugcheck/index.ts index 92cfab2..a058c2d 100644 --- a/src/langchain/rugcheck/index.ts +++ b/src/langchain/rugcheck/index.ts @@ -1,3 +1,2 @@ export * from "./token_report_summary"; export * from "./token_report_detailed"; -export * from "./types"; diff --git a/src/langchain/rugcheck/token_report_detailed.ts b/src/langchain/rugcheck/token_report_detailed.ts index 92bf6b1..9d45bac 100644 --- a/src/langchain/rugcheck/token_report_detailed.ts +++ b/src/langchain/rugcheck/token_report_detailed.ts @@ -1,12 +1,16 @@ -import { BaseSolanaTool } from "../common/base"; -import { TokenReportResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaFetchTokenDetailedReportTool extends BaseSolanaTool { +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(); @@ -17,9 +21,13 @@ export class SolanaFetchTokenDetailedReportTool extends BaseSolanaTool { status: "success", message: "Detailed token report fetched successfully", report: detailedReport, - } as TokenReportResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TOKEN_DETAILED_REPORT_ERROR", + }); } } } diff --git a/src/langchain/rugcheck/token_report_summary.ts b/src/langchain/rugcheck/token_report_summary.ts index ee7aeba..766abdb 100644 --- a/src/langchain/rugcheck/token_report_summary.ts +++ b/src/langchain/rugcheck/token_report_summary.ts @@ -1,12 +1,16 @@ -import { BaseSolanaTool } from "../common/base"; -import { TokenReportResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaFetchTokenReportSummaryTool extends BaseSolanaTool { +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(); @@ -16,9 +20,13 @@ export class SolanaFetchTokenReportSummaryTool extends BaseSolanaTool { status: "success", message: "Token report summary fetched successfully", report, - } as TokenReportResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TOKEN_REPORT_SUMMARY_ERROR", + }); } } } diff --git a/src/langchain/rugcheck/types.ts b/src/langchain/rugcheck/types.ts deleted file mode 100644 index 7d440a9..0000000 --- a/src/langchain/rugcheck/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface TokenCheckResult { - tokenProgram: string; - tokenType: string; - risks: Array<{ - name: string; - level: string; - description: string; - score: number; - }>; - score: number; -} - -export interface TokenReportResponse extends BaseToolResponse { - report?: TokenCheckResult; -} diff --git a/src/langchain/sendarcade/index.ts b/src/langchain/sendarcade/index.ts index 71aed69..9d6a8d7 100644 --- a/src/langchain/sendarcade/index.ts +++ b/src/langchain/sendarcade/index.ts @@ -1,2 +1 @@ export * from "./rock_paper_scissors"; -export * from "./types"; diff --git a/src/langchain/sendarcade/rock_paper_scissors.ts b/src/langchain/sendarcade/rock_paper_scissors.ts index 2c930d5..ab90107 100644 --- a/src/langchain/sendarcade/rock_paper_scissors.ts +++ b/src/langchain/sendarcade/rock_paper_scissors.ts @@ -1,7 +1,7 @@ -import { BaseSolanaTool } from "../common/base"; -import { RockPaperScissorsInput } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRockPaperScissorsTool extends BaseSolanaTool { +export class SolanaRockPaperScissorsTool extends Tool { name = "rock_paper_scissors"; description = `Play rock paper scissors to win SEND coins. @@ -9,12 +9,32 @@ export class SolanaRockPaperScissorsTool extends BaseSolanaTool { choice: string, either "rock", "paper", or "scissors" (required) amount: number, amount of SOL to play with - must be 0.1, 0.01, or 0.005 SOL (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + private validateInput(input: any): void { + if (input.choice !== undefined) { + throw new Error("choice is required."); + } + if ( + input.amount !== undefined && + (typeof input.spaceKB !== "number" || input.spaceKB <= 0) + ) { + throw new Error("amount must be a positive number when provided"); + } + } + protected async _call(input: string): Promise { try { - const params: RockPaperScissorsInput = JSON.parse(input); + const parsedInput = JSON.parse(input); + this.validateInput(parsedInput); const result = await this.solanaKit.rockPaperScissors( - params.amount, - params.choice, + Number(parsedInput['"amount"']), + parsedInput['"choice"'].replace(/^"|"$/g, "") as + | "rock" + | "paper" + | "scissors", ); return JSON.stringify({ @@ -22,7 +42,11 @@ export class SolanaRockPaperScissorsTool extends BaseSolanaTool { message: result, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/sendarcade/types.ts b/src/langchain/sendarcade/types.ts deleted file mode 100644 index 30f19f9..0000000 --- a/src/langchain/sendarcade/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface RockPaperScissorsInput { - choice: "rock" | "paper" | "scissors"; - amount: number; -} diff --git a/src/langchain/solana/balance.ts b/src/langchain/solana/balance.ts index 32cc541..fd84b88 100644 --- a/src/langchain/solana/balance.ts +++ b/src/langchain/solana/balance.ts @@ -1,7 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaBalanceTool extends BaseSolanaTool { +export class SolanaBalanceTool extends Tool { name = "solana_balance"; description = `Get the balance of a Solana wallet or token account. @@ -11,21 +12,26 @@ export class SolanaBalanceTool extends BaseSolanaTool { Inputs ( input is a JSON string ): tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = input ? JSON.parse(input) : {}; - const tokenAddress = params.tokenAddress - ? new PublicKey(params.tokenAddress) - : undefined; + const tokenAddress = input ? new PublicKey(input) : undefined; const balance = await this.solanaKit.getBalance(tokenAddress); return JSON.stringify({ status: "success", balance, - token: params.tokenAddress || "SOL", + token: input || "SOL", }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/solana/balance_other.ts b/src/langchain/solana/balance_other.ts index 5a1fdd8..c29f7f1 100644 --- a/src/langchain/solana/balance_other.ts +++ b/src/langchain/solana/balance_other.ts @@ -1,7 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaBalanceOtherTool extends BaseSolanaTool { +export class SolanaBalanceOtherTool extends Tool { name = "solana_balance_other"; description = `Get the balance of a Solana wallet or token account which is different from the agent's wallet. @@ -11,26 +12,35 @@ export class SolanaBalanceOtherTool extends BaseSolanaTool { walletAddress: string, eg "GDEkQF7UMr7RLv1KQKMtm8E2w3iafxJLtyXu3HVQZnME" (required) tokenAddress: string, eg "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = JSON.parse(input); - const tokenPubKey = params.tokenAddress - ? new PublicKey(params.tokenAddress) + const { walletAddress, tokenAddress } = JSON.parse(input); + + const tokenPubKey = tokenAddress + ? new PublicKey(tokenAddress) : undefined; const balance = await this.solanaKit.getBalanceOther( - new PublicKey(params.walletAddress), + new PublicKey(walletAddress), tokenPubKey, ); return JSON.stringify({ status: "success", balance, - wallet: params.walletAddress, - token: params.tokenAddress || "SOL", + wallet: walletAddress, + token: tokenAddress || "SOL", }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/solana/close_empty_accounts.ts b/src/langchain/solana/close_empty_accounts.ts index 9d82137..9a1bba9 100644 --- a/src/langchain/solana/close_empty_accounts.ts +++ b/src/langchain/solana/close_empty_accounts.ts @@ -1,9 +1,14 @@ -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaCloseEmptyTokenAccounts extends BaseSolanaTool { +export class SolanaCloseEmptyTokenAccounts extends Tool { name = "close_empty_token_accounts"; description = `Close all empty spl-token accounts and reclaim the rent`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(): Promise { try { const { signature, size } = @@ -13,10 +18,13 @@ export class SolanaCloseEmptyTokenAccounts extends BaseSolanaTool { status: "success", message: `${size} accounts closed successfully. ${size === 48 ? "48 accounts can be closed in a single transaction try again to close more accounts" : ""}`, signature, - size, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/solana/get_tps.ts b/src/langchain/solana/get_tps.ts index 92e300e..4f052d8 100644 --- a/src/langchain/solana/get_tps.ts +++ b/src/langchain/solana/get_tps.ts @@ -1,20 +1,20 @@ -import { BaseSolanaTool } from "../common/base"; -import { TPSResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaTPSCalculatorTool extends BaseSolanaTool { +export class SolanaTPSCalculatorTool extends Tool { name = "solana_get_tps"; description = "Get the current TPS of the Solana network"; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(_input: string): Promise { try { const tps = await this.solanaKit.getTPS(); - return JSON.stringify({ - status: "success", - message: `Current network TPS: ${tps}`, - tps, - } as TPSResponse); + return `Solana (mainnet-beta) current transactions per second: ${tps}`; } catch (error: any) { - return this.handleError(error); + return `Error fetching TPS: ${error.message}`; } } } diff --git a/src/langchain/solana/index.ts b/src/langchain/solana/index.ts index 9ed6edb..02db35c 100644 --- a/src/langchain/solana/index.ts +++ b/src/langchain/solana/index.ts @@ -4,4 +4,3 @@ export * from "./balance"; export * from "./balance_other"; export * from "./close_empty_accounts"; export * from "./transfer"; -export * from "./types"; diff --git a/src/langchain/solana/request_funds.ts b/src/langchain/solana/request_funds.ts index 024405c..832db99 100644 --- a/src/langchain/solana/request_funds.ts +++ b/src/langchain/solana/request_funds.ts @@ -1,10 +1,14 @@ -import { BaseSolanaTool } from "../common/base"; -import { BaseToolResponse } from "../common/types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRequestFundsTool extends BaseSolanaTool { +export class SolanaRequestFundsTool extends Tool { name = "solana_request_funds"; description = "Request SOL from Solana faucet (devnet/testnet only)"; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(_input: string): Promise { try { await this.solanaKit.requestFaucetFunds(); @@ -13,9 +17,13 @@ export class SolanaRequestFundsTool extends BaseSolanaTool { status: "success", message: "Successfully requested faucet funds", network: this.solanaKit.connection.rpcEndpoint.split("/")[2], - } as BaseToolResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/solana/transfer.ts b/src/langchain/solana/transfer.ts index de09b87..2f21ebf 100644 --- a/src/langchain/solana/transfer.ts +++ b/src/langchain/solana/transfer.ts @@ -1,7 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaTransferTool extends BaseSolanaTool { +export class SolanaTransferTool extends Tool { name = "solana_transfer"; description = `Transfer tokens or SOL to another address ( also called as wallet address ). @@ -10,29 +11,39 @@ export class SolanaTransferTool extends BaseSolanaTool { amount: number, eg 1 (required) mint?: string, eg "So11111111111111111111111111111111111111112" or "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = JSON.parse(input); + const parsedInput = JSON.parse(input); - const recipient = new PublicKey(params.to); - const mintAddress = params.mint ? new PublicKey(params.mint) : undefined; + const recipient = new PublicKey(parsedInput.to); + const mintAddress = parsedInput.mint + ? new PublicKey(parsedInput.mint) + : undefined; const tx = await this.solanaKit.transfer( recipient, - params.amount, + parsedInput.amount, mintAddress, ); return JSON.stringify({ status: "success", message: "Transfer completed successfully", - amount: params.amount, - recipient: params.to, - token: params.mint || "SOL", + amount: parsedInput.amount, + recipient: parsedInput.to, + token: parsedInput.mint || "SOL", transaction: tx, }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/solana/types.ts b/src/langchain/solana/types.ts deleted file mode 100644 index 6adb097..0000000 --- a/src/langchain/solana/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface CreateImageResponse extends BaseToolResponse { - images?: string[]; -} - -export interface TPSResponse extends BaseToolResponse { - tps?: number; -} - -export interface WalletAddressResponse extends BaseToolResponse { - address?: string; -} diff --git a/src/langchain/solayer/restake.ts b/src/langchain/solayer/restake.ts index 0d8eb55..d13291f 100644 --- a/src/langchain/solayer/restake.ts +++ b/src/langchain/solayer/restake.ts @@ -1,13 +1,17 @@ -import { BaseSolanaTool } from "../common/base"; -import { StakeResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRestakeTool extends BaseSolanaTool { +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 { try { const parsedInput = JSON.parse(input) || Number(input); @@ -19,9 +23,13 @@ export class SolanaRestakeTool extends BaseSolanaTool { message: "Staked successfully", transaction: tx, amount: parsedInput.amount, - } as StakeResponse); + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/squads_multisig/approve_proposal.ts b/src/langchain/squads_multisig/approve_proposal.ts index 50f5147..23bac26 100644 --- a/src/langchain/squads_multisig/approve_proposal.ts +++ b/src/langchain/squads_multisig/approve_proposal.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaApproveProposal2by2Multisig extends BaseSolanaTool { +export class SolanaApproveProposal2by2Multisig extends Tool { name = "approve_proposal_2by2_multisig"; description = `Approve a proposal to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. @@ -9,6 +10,10 @@ export class SolanaApproveProposal2by2Multisig extends BaseSolanaTool { Inputs (JSON string): - proposalIndex: number, the index of the proposal (optional).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/squads_multisig/create_multisig.ts b/src/langchain/squads_multisig/create_multisig.ts index 683cff2..4628d25 100644 --- a/src/langchain/squads_multisig/create_multisig.ts +++ b/src/langchain/squads_multisig/create_multisig.ts @@ -1,7 +1,8 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import { PublicKey } from "@solana/web3.js"; -export class SolanaCreate2by2Multisig extends BaseSolanaTool { +export class SolanaCreate2by2Multisig extends Tool { name = "create_2by2_multisig"; description = `Create a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. @@ -10,6 +11,10 @@ export class SolanaCreate2by2Multisig extends BaseSolanaTool { Inputs (JSON string): - creator: string, the public key of the creator (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/squads_multisig/create_proposal.ts b/src/langchain/squads_multisig/create_proposal.ts index 46ef85b..fb79cde 100644 --- a/src/langchain/squads_multisig/create_proposal.ts +++ b/src/langchain/squads_multisig/create_proposal.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaCreateProposal2by2Multisig extends BaseSolanaTool { +export class SolanaCreateProposal2by2Multisig extends Tool { name = "create_proposal_2by2_multisig"; description = `Create a proposal to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. @@ -9,6 +10,10 @@ export class SolanaCreateProposal2by2Multisig extends BaseSolanaTool { Inputs (JSON string): - transactionIndex: number, the index of the transaction (optional).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/squads_multisig/deposit_to_multisig.ts b/src/langchain/squads_multisig/deposit_to_multisig.ts index bb49b45..4e9645c 100644 --- a/src/langchain/squads_multisig/deposit_to_multisig.ts +++ b/src/langchain/squads_multisig/deposit_to_multisig.ts @@ -1,13 +1,18 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import Decimal from "decimal.js"; -export class SolanaDepositTo2by2Multisig extends BaseSolanaTool { +export class SolanaDepositTo2by2Multisig extends Tool { name = "deposit_to_2by2_multisig"; description = `Deposit funds to a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. Inputs (JSON string): - amount: number, the amount to deposit in SOL (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/squads_multisig/execute_proposal.ts b/src/langchain/squads_multisig/execute_proposal.ts index 08156aa..4c6463b 100644 --- a/src/langchain/squads_multisig/execute_proposal.ts +++ b/src/langchain/squads_multisig/execute_proposal.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaExecuteProposal2by2Multisig extends BaseSolanaTool { +export class SolanaExecuteProposal2by2Multisig extends Tool { name = "execute_proposal_2by2_multisig"; description = `Execute a proposal/transaction to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. @@ -9,6 +10,10 @@ export class SolanaExecuteProposal2by2Multisig extends BaseSolanaTool { Inputs (JSON string): - proposalIndex: number, the index of the proposal (optional).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/squads_multisig/reject_proposal.ts b/src/langchain/squads_multisig/reject_proposal.ts index 01c618b..30a62fc 100644 --- a/src/langchain/squads_multisig/reject_proposal.ts +++ b/src/langchain/squads_multisig/reject_proposal.ts @@ -1,6 +1,7 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaRejectProposal2by2Multisig extends BaseSolanaTool { +export class SolanaRejectProposal2by2Multisig extends Tool { name = "reject_proposal_2by2_multisig"; description = `Reject a proposal to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. @@ -9,6 +10,10 @@ export class SolanaRejectProposal2by2Multisig extends BaseSolanaTool { Inputs (JSON string): - proposalIndex: number, the index of the proposal (optional).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/squads_multisig/transfer_from_multisig.ts b/src/langchain/squads_multisig/transfer_from_multisig.ts index 7fd841c..ef657ff 100644 --- a/src/langchain/squads_multisig/transfer_from_multisig.ts +++ b/src/langchain/squads_multisig/transfer_from_multisig.ts @@ -1,8 +1,9 @@ -import { BaseSolanaTool } from "../common"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; import { PublicKey } from "@solana/web3.js"; import Decimal from "decimal.js"; -export class SolanaTransferFrom2by2Multisig extends BaseSolanaTool { +export class SolanaTransferFrom2by2Multisig extends Tool { name = "transfer_from_2by2_multisig"; description = `Create a transaction to transfer funds from a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions. @@ -10,6 +11,10 @@ export class SolanaTransferFrom2by2Multisig extends BaseSolanaTool { - amount: number, the amount to transfer in SOL (required). - recipient: string, the public key of the recipient (required).`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); diff --git a/src/langchain/tensor/cancel_listing.ts b/src/langchain/tensor/cancel_listing.ts index effdc4b..8fd764d 100644 --- a/src/langchain/tensor/cancel_listing.ts +++ b/src/langchain/tensor/cancel_listing.ts @@ -1,30 +1,38 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { NFTListingResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaCancelNFTListingTool extends BaseSolanaTool { +export class SolanaCancelNFTListingTool extends Tool { name = "solana_cancel_nft_listing"; description = `Cancel an NFT listing on Tensor Trade. Inputs (input is a JSON string): nftMint: string, the mint address of the NFT (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params = JSON.parse(input); + const parsedInput = JSON.parse(input); const tx = await this.solanaKit.tensorCancelListing( - new PublicKey(params.nftMint), + new PublicKey(parsedInput.nftMint), ); return JSON.stringify({ status: "success", message: "NFT listing cancelled successfully", transaction: tx, - nftMint: params.nftMint, - } as NFTListingResponse); + nftMint: parsedInput.nftMint, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/tensor/list_nft.ts b/src/langchain/tensor/list_nft.ts index 0d91320..a54ea2b 100644 --- a/src/langchain/tensor/list_nft.ts +++ b/src/langchain/tensor/list_nft.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { ListNFTInput, NFTListingResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaListNFTForSaleTool extends BaseSolanaTool { +export class SolanaListNFTForSaleTool extends Tool { name = "solana_list_nft_for_sale"; description = `List an NFT for sale on Tensor Trade. @@ -10,15 +10,19 @@ export class SolanaListNFTForSaleTool extends BaseSolanaTool { nftMint: string, the mint address of the NFT (required) price: number, price in SOL (required)`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params: ListNFTInput = JSON.parse(input); + const parsedInput = JSON.parse(input); - // Validate NFT ownership + // Validate NFT ownership first const nftAccount = await this.solanaKit.connection.getTokenAccountsByOwner( this.solanaKit.wallet_address, - { mint: new PublicKey(params.nftMint) }, + { mint: new PublicKey(parsedInput.nftMint) }, ); if (nftAccount.value.length === 0) { @@ -27,23 +31,27 @@ export class SolanaListNFTForSaleTool extends BaseSolanaTool { message: "NFT not found in wallet. Please make sure you own this NFT.", code: "NFT_NOT_FOUND", - } as NFTListingResponse); + }); } const tx = await this.solanaKit.tensorListNFT( - new PublicKey(params.nftMint), - params.price, + new PublicKey(parsedInput.nftMint), + parsedInput.price, ); return JSON.stringify({ status: "success", message: "NFT listed for sale successfully", transaction: tx, - price: params.price, - nftMint: params.nftMint, - } as NFTListingResponse); + price: parsedInput.price, + nftMint: parsedInput.nftMint, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/tensor/types.ts b/src/langchain/tensor/types.ts deleted file mode 100644 index 2ff243f..0000000 --- a/src/langchain/tensor/types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface ListNFTInput { - nftMint: string; - price: number; -} - -export interface MintNFTResponse extends BaseToolResponse { - mintAddress?: string; - metadata?: { - name: string; - symbol?: string; - uri: string; - }; - recipient?: string; -} - -export interface NFTListingResponse extends BaseToolResponse { - transaction?: string; - price?: number; - nftMint?: string; -} diff --git a/src/langchain/tiplink/index.ts b/src/langchain/tiplink/index.ts index 207c6f6..b480c71 100644 --- a/src/langchain/tiplink/index.ts +++ b/src/langchain/tiplink/index.ts @@ -1,2 +1 @@ export * from "./tiplink"; -export * from "./types"; diff --git a/src/langchain/tiplink/tiplink.ts b/src/langchain/tiplink/tiplink.ts index f680076..f029b3b 100644 --- a/src/langchain/tiplink/tiplink.ts +++ b/src/langchain/tiplink/tiplink.ts @@ -1,25 +1,29 @@ import { PublicKey } from "@solana/web3.js"; -import { BaseSolanaTool } from "../common/base"; -import { TipLinkInput, TipLinkResponse } from "./types"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; -export class SolanaTipLinkTool extends BaseSolanaTool { +export class SolanaTipLinkTool extends Tool { name = "solana_tiplink"; description = `Create a TipLink for transferring SOL or SPL tokens. Input is a JSON string with: - amount: number (required) - Amount to transfer - splmintAddress: string (optional) - SPL token mint address`; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + protected async _call(input: string): Promise { try { - const params: TipLinkInput = JSON.parse(input); + const parsedInput = JSON.parse(input); - if (!params.amount) { + if (!parsedInput.amount) { throw new Error("Amount is required"); } - const amount = parseFloat(params.amount.toString()); - const splmintAddress = params.splmintAddress - ? new PublicKey(params.splmintAddress) + const amount = parseFloat(parsedInput.amount); + const splmintAddress = parsedInput.splmintAddress + ? new PublicKey(parsedInput.splmintAddress) : undefined; const { url, signature } = await this.solanaKit.createTiplink( @@ -29,14 +33,18 @@ export class SolanaTipLinkTool extends BaseSolanaTool { return JSON.stringify({ status: "success", - message: "TipLink created successfully", url, signature, amount, tokenType: splmintAddress ? "SPL" : "SOL", - } as TipLinkResponse); + message: `TipLink created successfully`, + }); } catch (error: any) { - return this.handleError(error); + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); } } } diff --git a/src/langchain/tiplink/types.ts b/src/langchain/tiplink/types.ts deleted file mode 100644 index 285f002..0000000 --- a/src/langchain/tiplink/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseToolResponse } from "../common/types"; - -export interface TipLinkInput { - amount: number; - splmintAddress?: string; -} - -export interface TipLinkResponse extends BaseToolResponse { - url?: string; - signature?: string; - amount?: number; - tokenType?: "SOL" | "SPL"; -}