diff --git a/src/actions/createImage.ts b/src/actions/agent/createImage.ts similarity index 95% rename from src/actions/createImage.ts rename to src/actions/agent/createImage.ts index adbf55c..140cc72 100644 --- a/src/actions/createImage.ts +++ b/src/actions/agent/createImage.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { create_image } from "../tools/create_image"; +import { create_image } from "../../tools/agent"; const createImageAction: Action = { name: "CREATE_IMAGE", diff --git a/src/actions/getWalletAddress.ts b/src/actions/agent/getWalletAddress.ts similarity index 80% rename from src/actions/getWalletAddress.ts rename to src/actions/agent/getWalletAddress.ts index 7cd87c6..00b7672 100644 --- a/src/actions/getWalletAddress.ts +++ b/src/actions/agent/getWalletAddress.ts @@ -1,7 +1,7 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { SolanaAgentKit } from ".."; -import { get_wallet_address } from "../tools"; -import { Action } from "../types/action"; +import { get_wallet_address } from "../../tools/agent"; const getWalletAddressAction: Action = { name: "GET_WALLET_ADDRESS", diff --git a/src/actions/getAllDomainsTLDs.ts b/src/actions/alldomains/getAllDomainsTLDs.ts similarity index 89% rename from src/actions/getAllDomainsTLDs.ts rename to src/actions/alldomains/getAllDomainsTLDs.ts index d8d2b64..3ab642e 100644 --- a/src/actions/getAllDomainsTLDs.ts +++ b/src/actions/alldomains/getAllDomainsTLDs.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { getAllDomainsTLDs } from "../tools"; +import { getAllDomainsTLDs } from "../../tools"; const getAllDomainsTLDsAction: Action = { name: "GET_ALL_TLDS", diff --git a/src/actions/getOwnedAllDomains.ts b/src/actions/alldomains/getOwnedAllDomains.ts similarity index 91% rename from src/actions/getOwnedAllDomains.ts rename to src/actions/alldomains/getOwnedAllDomains.ts index e9f294a..78f4d48 100644 --- a/src/actions/getOwnedAllDomains.ts +++ b/src/actions/alldomains/getOwnedAllDomains.ts @@ -1,8 +1,8 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; -import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { getOwnedAllDomains } from "../tools"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { getOwnedAllDomains } from "../../tools"; const getOwnedAllDomainsAction: Action = { name: "GET_OWNED_ALL_DOMAINS", diff --git a/src/actions/getOwnedDomainsForTLD.ts b/src/actions/alldomains/getOwnedDomainsForTLD.ts similarity index 91% rename from src/actions/getOwnedDomainsForTLD.ts rename to src/actions/alldomains/getOwnedDomainsForTLD.ts index 4343488..d49f30b 100644 --- a/src/actions/getOwnedDomainsForTLD.ts +++ b/src/actions/alldomains/getOwnedDomainsForTLD.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { getOwnedDomainsForTLD } from "../tools"; +import { getOwnedDomainsForTLD } from "../../tools"; const getOwnedDomainsForTLDAction: Action = { name: "GET_OWNED_DOMAINS_FOR_TLD", diff --git a/src/actions/resolveDomain.ts b/src/actions/alldomains/resolveDomain.ts similarity index 89% rename from src/actions/resolveDomain.ts rename to src/actions/alldomains/resolveDomain.ts index e54adea..347a0d6 100644 --- a/src/actions/resolveDomain.ts +++ b/src/actions/alldomains/resolveDomain.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { resolveAllDomains } from "../tools"; +import { resolveAllDomains } from "../../tools"; const resolveDomainAction: Action = { name: "RESOLVE_ALL_DOMAINS", diff --git a/src/actions/tokenDataByTicker.ts b/src/actions/dexscreener/tokenDataByTicker.ts similarity index 90% rename from src/actions/tokenDataByTicker.ts rename to src/actions/dexscreener/tokenDataByTicker.ts index 28995a5..5991a65 100644 --- a/src/actions/tokenDataByTicker.ts +++ b/src/actions/dexscreener/tokenDataByTicker.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { getTokenDataByTicker } from "../tools"; +import { getTokenDataByTicker } from "../../tools/dexscreener"; const tokenDataByTickerAction: Action = { name: "GET_TOKEN_DATA_BY_TICKER", diff --git a/src/actions/flashCloseTrade.ts b/src/actions/flash/flashCloseTrade.ts similarity index 91% rename from src/actions/flashCloseTrade.ts rename to src/actions/flash/flashCloseTrade.ts index 3781d83..6b7e34a 100644 --- a/src/actions/flashCloseTrade.ts +++ b/src/actions/flash/flashCloseTrade.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { flashCloseTrade } from "../tools"; +import { flashCloseTrade } from "../../tools/flash"; const flashCloseTradeAction: Action = { name: "FLASH_CLOSE_TRADE", diff --git a/src/actions/flashOpenTrade.ts b/src/actions/flash/flashOpenTrade.ts similarity index 93% rename from src/actions/flashOpenTrade.ts rename to src/actions/flash/flashOpenTrade.ts index 790bdef..b0db660 100644 --- a/src/actions/flashOpenTrade.ts +++ b/src/actions/flash/flashOpenTrade.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { flashOpenTrade } from "../tools"; +import { flashOpenTrade } from "../../tools/flash"; const flashOpenTradeAction: Action = { name: "FLASH_OPEN_TRADE", diff --git a/src/actions/createGibworkTask.ts b/src/actions/gibwork/createGibworkTask.ts similarity index 94% rename from src/actions/createGibworkTask.ts rename to src/actions/gibwork/createGibworkTask.ts index 12aa809..dc4b672 100644 --- a/src/actions/createGibworkTask.ts +++ b/src/actions/gibwork/createGibworkTask.ts @@ -1,8 +1,8 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { create_gibwork_task } from "../tools"; +import { create_gibwork_task } from "../../tools/gibwork"; const createGibworkTaskAction: Action = { name: "CREATE_GIBWORK_TASK", diff --git a/src/actions/index.ts b/src/actions/index.ts index c974209..e878aa1 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -1,35 +1,35 @@ -import deployTokenAction from "./deployToken"; -import balanceAction from "./balance"; -import transferAction from "./transfer"; -import deployCollectionAction from "./deployCollection"; -import mintNFTAction from "./mintNFT"; -import tradeAction from "./trade"; -import requestFundsAction from "./requestFunds"; -import resolveDomainAction from "./resolveDomain"; -import getTokenDataAction from "./getTokenData"; -import getTPSAction from "./getTPS"; -import fetchPriceAction from "./fetchPrice"; -import stakeWithJupAction from "./stakeWithJup"; -import stakeWithSolayerAction from "./stakeWithSolayer"; -import registerDomainAction from "./registerDomain"; -import lendAssetAction from "./lendAsset"; -import createGibworkTaskAction from "./createGibworkTask"; -import resolveSolDomainAction from "./resolveSolDomain"; -import pythFetchPriceAction from "./pythFetchPrice"; -import getOwnedDomainsForTLDAction from "./getOwnedDomainsForTLD"; -import getPrimaryDomainAction from "./getPrimaryDomain"; -import getAllDomainsTLDsAction from "./getAllDomainsTLDs"; -import getOwnedAllDomainsAction from "./getOwnedAllDomains"; -import createImageAction from "./createImage"; -import getMainAllDomainsDomainAction from "./getMainAllDomainsDomain"; -import getAllRegisteredAllDomainsAction from "./getAllRegisteredAllDomains"; -import raydiumCreateCpmmAction from "./raydiumCreateCpmm"; -import raydiumCreateAmmV4Action from "./raydiumCreateAmmV4"; -import createOrcaSingleSidedWhirlpoolAction from "./createOrcaSingleSidedWhirlpool"; -import launchPumpfunTokenAction from "./launchPumpfunToken"; -import getWalletAddressAction from "./getWalletAddress"; -import flashOpenTradeAction from "./flashOpenTrade"; -import flashCloseTradeAction from "./flashCloseTrade"; +import deployTokenAction from "./metaplex/deployToken"; +import balanceAction from "./solana/balance"; +import transferAction from "./solana/transfer"; +import deployCollectionAction from "./metaplex/deployCollection"; +import mintNFTAction from "./metaplex/mintNFT"; +import tradeAction from "./jupiter/trade"; +import requestFundsAction from "./solana/requestFunds"; +import resolveDomainAction from "./sns/registerDomain"; +import getTokenDataAction from "./jupiter/getTokenData"; +import getTPSAction from "./solana/getTPS"; +import fetchPriceAction from "./jupiter/fetchPrice"; +import stakeWithJupAction from "./jupiter/stakeWithJup"; +import stakeWithSolayerAction from "./solayer/stakeWithSolayer"; +import registerDomainAction from "./sns/registerDomain"; +import lendAssetAction from "./lulo/lendAsset"; +import createGibworkTaskAction from "./gibwork/createGibworkTask"; +import resolveSolDomainAction from "./sns/resolveSolDomain"; +import pythFetchPriceAction from "./pyth/pythFetchPrice"; +import getOwnedDomainsForTLDAction from "./alldomains/getOwnedDomainsForTLD"; +import getPrimaryDomainAction from "./sns/getPrimaryDomain"; +import getAllDomainsTLDsAction from "./alldomains/getAllDomainsTLDs"; +import getOwnedAllDomainsAction from "./alldomains/getOwnedAllDomains"; +import createImageAction from "./agent/createImage"; +import getMainAllDomainsDomainAction from "./sns/getMainAllDomainsDomain"; +import getAllRegisteredAllDomainsAction from "./sns/getAllRegisteredAllDomains"; +import raydiumCreateCpmmAction from "./raydium/raydiumCreateCpmm"; +import raydiumCreateAmmV4Action from "./raydium/raydiumCreateAmmV4"; +import createOrcaSingleSidedWhirlpoolAction from "./orca/createOrcaSingleSidedWhirlpool"; +import launchPumpfunTokenAction from "./pumpfun/launchPumpfunToken"; +import getWalletAddressAction from "./agent/getWalletAddress"; +import flashOpenTradeAction from "./flash/flashOpenTrade"; +import flashCloseTradeAction from "./flash/flashCloseTrade"; export const ACTIONS = { WALLET_ADDRESS_ACTION: getWalletAddressAction, diff --git a/src/actions/fetchPrice.ts b/src/actions/jupiter/fetchPrice.ts similarity index 90% rename from src/actions/fetchPrice.ts rename to src/actions/jupiter/fetchPrice.ts index b232671..d16a371 100644 --- a/src/actions/fetchPrice.ts +++ b/src/actions/jupiter/fetchPrice.ts @@ -1,8 +1,8 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { fetchPrice } from "../tools"; +import { fetchPrice } from "../../tools/jupiter"; const fetchPriceAction: Action = { name: "FETCH_PRICE", diff --git a/src/actions/getTokenData.ts b/src/actions/jupiter/getTokenData.ts similarity index 94% rename from src/actions/getTokenData.ts rename to src/actions/jupiter/getTokenData.ts index bf820dc..6b7f308 100644 --- a/src/actions/getTokenData.ts +++ b/src/actions/jupiter/getTokenData.ts @@ -1,9 +1,9 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { JupiterTokenData } from "../types"; -import { getTokenAddressFromTicker, getTokenDataByAddress } from "../tools"; +import { JupiterTokenData } from "../../types"; +import { getTokenAddressFromTicker, getTokenDataByAddress } from "../../tools"; const getTokenDataAction: Action = { name: "GET_TOKEN_DATA", diff --git a/src/actions/stakeWithJup.ts b/src/actions/jupiter/stakeWithJup.ts similarity index 90% rename from src/actions/stakeWithJup.ts rename to src/actions/jupiter/stakeWithJup.ts index 7f7680f..34cf91b 100644 --- a/src/actions/stakeWithJup.ts +++ b/src/actions/jupiter/stakeWithJup.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { stakeWithJup } from "../tools"; +import { stakeWithJup } from "../../tools"; const stakeWithJupAction: Action = { name: "STAKE_WITH_JUPITER", diff --git a/src/actions/trade.ts b/src/actions/jupiter/trade.ts similarity index 95% rename from src/actions/trade.ts rename to src/actions/jupiter/trade.ts index a4c9e48..4710990 100644 --- a/src/actions/trade.ts +++ b/src/actions/jupiter/trade.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { trade } from "../tools"; +import { trade } from "../../tools"; const tradeAction: Action = { name: "TRADE", diff --git a/src/actions/compressedAirdrop.ts b/src/actions/lightprotocol/compressedAirdrop.ts similarity index 95% rename from src/actions/compressedAirdrop.ts rename to src/actions/lightprotocol/compressedAirdrop.ts index 107d352..2abdc72 100644 --- a/src/actions/compressedAirdrop.ts +++ b/src/actions/lightprotocol/compressedAirdrop.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { sendCompressedAirdrop } from "../tools"; +import { sendCompressedAirdrop } from "../../tools"; const compressedAirdropAction: Action = { name: "COMPRESSED_AIRDROP", diff --git a/src/actions/lendAsset.ts b/src/actions/lulo/lendAsset.ts similarity index 89% rename from src/actions/lendAsset.ts rename to src/actions/lulo/lendAsset.ts index 9ceb20e..3c29f91 100644 --- a/src/actions/lendAsset.ts +++ b/src/actions/lulo/lendAsset.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { lendAsset } from "../tools"; +import { lendAsset } from "../../tools/lulo"; const lendAssetAction: Action = { name: "LEND_ASSET", diff --git a/src/actions/deployCollection.ts b/src/actions/metaplex/deployCollection.ts similarity index 93% rename from src/actions/deployCollection.ts rename to src/actions/metaplex/deployCollection.ts index 1ca5e14..dc0e5c0 100644 --- a/src/actions/deployCollection.ts +++ b/src/actions/metaplex/deployCollection.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { deploy_collection } from "../tools"; +import { deploy_collection } from "../../tools/metaplex"; interface CollectionOptions { name: string; diff --git a/src/actions/deployToken.ts b/src/actions/metaplex/deployToken.ts similarity index 93% rename from src/actions/deployToken.ts rename to src/actions/metaplex/deployToken.ts index 3a3f25d..02c5a51 100644 --- a/src/actions/deployToken.ts +++ b/src/actions/metaplex/deployToken.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { deploy_token } from "../tools"; +import { deploy_token } from "../../tools"; const deployTokenAction: Action = { name: "DEPLOY_TOKEN", diff --git a/src/actions/mintNFT.ts b/src/actions/metaplex/mintNFT.ts similarity index 94% rename from src/actions/mintNFT.ts rename to src/actions/metaplex/mintNFT.ts index f04cfb7..f0810be 100644 --- a/src/actions/mintNFT.ts +++ b/src/actions/metaplex/mintNFT.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { mintCollectionNFT } from "../tools"; +import { mintCollectionNFT } from "../../tools/metaplex"; const mintNFTAction: Action = { name: "MINT_NFT", diff --git a/src/actions/createOpenbookMarket.ts b/src/actions/openbook/createOpenbookMarket.ts similarity index 93% rename from src/actions/createOpenbookMarket.ts rename to src/actions/openbook/createOpenbookMarket.ts index ae76559..f978d35 100644 --- a/src/actions/createOpenbookMarket.ts +++ b/src/actions/openbook/createOpenbookMarket.ts @@ -1,8 +1,8 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; -import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { openbookCreateMarket } from "../tools"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { openbookCreateMarket } from "../../tools/openbook"; const createOpenbookMarketAction: Action = { name: "CREATE_OPENBOOK_MARKET", diff --git a/src/actions/createOrcaSingleSidedWhirlpool.ts b/src/actions/orca/createOrcaSingleSidedWhirlpool.ts similarity index 95% rename from src/actions/createOrcaSingleSidedWhirlpool.ts rename to src/actions/orca/createOrcaSingleSidedWhirlpool.ts index f53c881..97eaca0 100644 --- a/src/actions/createOrcaSingleSidedWhirlpool.ts +++ b/src/actions/orca/createOrcaSingleSidedWhirlpool.ts @@ -1,9 +1,9 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; import { Decimal } from "decimal.js"; -import { orcaCreateSingleSidedLiquidityPool } from "../tools"; +import { orcaCreateSingleSidedLiquidityPool } from "../../tools"; // Fee tiers mapping from the original tool const FEE_TIERS = { diff --git a/src/actions/launchPumpfunToken.ts b/src/actions/pumpfun/launchPumpfunToken.ts similarity index 95% rename from src/actions/launchPumpfunToken.ts rename to src/actions/pumpfun/launchPumpfunToken.ts index 3c23394..8d64c0c 100644 --- a/src/actions/launchPumpfunToken.ts +++ b/src/actions/pumpfun/launchPumpfunToken.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { launchPumpFunToken } from "../tools"; +import { launchPumpFunToken } from "../../tools"; const launchPumpfunTokenAction: Action = { name: "LAUNCH_PUMPFUN_TOKEN", diff --git a/src/actions/pythFetchPrice.ts b/src/actions/pyth/pythFetchPrice.ts similarity index 89% rename from src/actions/pythFetchPrice.ts rename to src/actions/pyth/pythFetchPrice.ts index d9f7ae4..fb06de9 100644 --- a/src/actions/pythFetchPrice.ts +++ b/src/actions/pyth/pythFetchPrice.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { fetchPythPrice, fetchPythPriceFeedID } from "../tools"; +import { fetchPythPrice, fetchPythPriceFeedID } from "../../tools"; const pythFetchPriceAction: Action = { name: "PYTH_FETCH_PRICE", diff --git a/src/actions/raydiumCreateAmmV4.ts b/src/actions/raydium/raydiumCreateAmmV4.ts similarity index 94% rename from src/actions/raydiumCreateAmmV4.ts rename to src/actions/raydium/raydiumCreateAmmV4.ts index 8ad228d..b6c496b 100644 --- a/src/actions/raydiumCreateAmmV4.ts +++ b/src/actions/raydium/raydiumCreateAmmV4.ts @@ -1,9 +1,9 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; -import { raydiumCreateAmmV4 } from "../tools"; +import { raydiumCreateAmmV4 } from "../../tools"; const raydiumCreateAmmV4Action: Action = { name: "RAYDIUM_CREATE_AMM_V4", diff --git a/src/actions/raydiumCreateClmm.ts b/src/actions/raydium/raydiumCreateClmm.ts similarity index 94% rename from src/actions/raydiumCreateClmm.ts rename to src/actions/raydium/raydiumCreateClmm.ts index dd24322..cb77605 100644 --- a/src/actions/raydiumCreateClmm.ts +++ b/src/actions/raydium/raydiumCreateClmm.ts @@ -1,10 +1,10 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; import { BN } from "@coral-xyz/anchor"; import Decimal from "decimal.js"; -import { raydiumCreateClmm } from "../tools"; +import { raydiumCreateClmm } from "../../tools"; const raydiumCreateClmmAction: Action = { name: "RAYDIUM_CREATE_CLMM", diff --git a/src/actions/raydiumCreateCpmm.ts b/src/actions/raydium/raydiumCreateCpmm.ts similarity index 94% rename from src/actions/raydiumCreateCpmm.ts rename to src/actions/raydium/raydiumCreateCpmm.ts index b2159b5..ee74d9e 100644 --- a/src/actions/raydiumCreateCpmm.ts +++ b/src/actions/raydium/raydiumCreateCpmm.ts @@ -1,9 +1,9 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; -import { raydiumCreateCpmm } from "../tools"; +import { raydiumCreateCpmm } from "../../tools"; const raydiumCreateCpmmAction: Action = { name: "RAYDIUM_CREATE_CPMM", diff --git a/src/actions/getAllRegisteredAllDomains.ts b/src/actions/sns/getAllRegisteredAllDomains.ts similarity index 92% rename from src/actions/getAllRegisteredAllDomains.ts rename to src/actions/sns/getAllRegisteredAllDomains.ts index a4d5688..541c069 100644 --- a/src/actions/getAllRegisteredAllDomains.ts +++ b/src/actions/sns/getAllRegisteredAllDomains.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { getAllRegisteredAllDomains } from "../tools"; +import { getAllRegisteredAllDomains } from "../../tools"; const getAllRegisteredAllDomainsAction: Action = { name: "GET_ALL_REGISTERED_ALL_DOMAINS", diff --git a/src/actions/getMainAllDomainsDomain.ts b/src/actions/sns/getMainAllDomainsDomain.ts similarity index 91% rename from src/actions/getMainAllDomainsDomain.ts rename to src/actions/sns/getMainAllDomainsDomain.ts index 1071050..7ab7488 100644 --- a/src/actions/getMainAllDomainsDomain.ts +++ b/src/actions/sns/getMainAllDomainsDomain.ts @@ -1,8 +1,8 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; -import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { getMainAllDomainsDomain } from "../tools"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { getMainAllDomainsDomain } from "../../tools"; const getMainAllDomainsDomainAction: Action = { name: "GET_MAIN_ALL_DOMAINS_DOMAIN", diff --git a/src/actions/getPrimaryDomain.ts b/src/actions/sns/getPrimaryDomain.ts similarity index 90% rename from src/actions/getPrimaryDomain.ts rename to src/actions/sns/getPrimaryDomain.ts index 2655dae..b5fd0d2 100644 --- a/src/actions/getPrimaryDomain.ts +++ b/src/actions/sns/getPrimaryDomain.ts @@ -1,8 +1,8 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; -import { z } from "zod"; import { PublicKey } from "@solana/web3.js"; -import { getPrimaryDomain } from "../tools"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { getPrimaryDomain } from "../../tools"; const getPrimaryDomainAction: Action = { name: "GET_PRIMARY_DOMAIN", diff --git a/src/actions/registerDomain.ts b/src/actions/sns/registerDomain.ts similarity index 91% rename from src/actions/registerDomain.ts rename to src/actions/sns/registerDomain.ts index 55f9354..9f1badb 100644 --- a/src/actions/registerDomain.ts +++ b/src/actions/sns/registerDomain.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { registerDomain } from "../tools"; +import { registerDomain } from "../../tools"; const registerDomainAction: Action = { name: "REGISTER_DOMAIN", diff --git a/src/actions/resolveSolDomain.ts b/src/actions/sns/resolveSolDomain.ts similarity index 90% rename from src/actions/resolveSolDomain.ts rename to src/actions/sns/resolveSolDomain.ts index 60281e2..56242c6 100644 --- a/src/actions/resolveSolDomain.ts +++ b/src/actions/sns/resolveSolDomain.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { resolveSolDomain } from "../tools"; +import { resolveSolDomain } from "../../tools/"; const resolveSolDomainAction: Action = { name: "RESOLVE_SOL_DOMAIN", diff --git a/src/actions/balance.ts b/src/actions/solana/balance.ts similarity index 91% rename from src/actions/balance.ts rename to src/actions/solana/balance.ts index 381b2a5..1009033 100644 --- a/src/actions/balance.ts +++ b/src/actions/solana/balance.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { get_balance } from "../tools"; +import { get_balance } from "../../tools"; const balanceAction: Action = { name: "BALANCE_ACTION", diff --git a/src/actions/closeEmptyTokenAccounts.ts b/src/actions/solana/closeEmptyTokenAccounts.ts similarity index 92% rename from src/actions/closeEmptyTokenAccounts.ts rename to src/actions/solana/closeEmptyTokenAccounts.ts index 867c25e..85fb67b 100644 --- a/src/actions/closeEmptyTokenAccounts.ts +++ b/src/actions/solana/closeEmptyTokenAccounts.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { closeEmptyTokenAccounts } from "../tools"; +import { closeEmptyTokenAccounts } from "../../tools"; const closeEmptyTokenAccountsAction: Action = { name: "CLOSE_EMPTY_TOKEN_ACCOUNTS", diff --git a/src/actions/getTPS.ts b/src/actions/solana/getTPS.ts similarity index 88% rename from src/actions/getTPS.ts rename to src/actions/solana/getTPS.ts index 490bfb4..69fce8d 100644 --- a/src/actions/getTPS.ts +++ b/src/actions/solana/getTPS.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { getTPS } from "../tools"; +import { getTPS } from "../../tools/solana"; const getTPSAction: Action = { name: "GET_TPS", diff --git a/src/actions/requestFunds.ts b/src/actions/solana/requestFunds.ts similarity index 86% rename from src/actions/requestFunds.ts rename to src/actions/solana/requestFunds.ts index a4a95c2..8ce5d2f 100644 --- a/src/actions/requestFunds.ts +++ b/src/actions/solana/requestFunds.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { request_faucet_funds } from "../tools"; +import { request_faucet_funds } from "../../tools/solana"; const requestFundsAction: Action = { name: "REQUEST_FUNDS", diff --git a/src/actions/transfer.ts b/src/actions/solana/transfer.ts similarity index 94% rename from src/actions/transfer.ts rename to src/actions/solana/transfer.ts index f4206aa..568d1a3 100644 --- a/src/actions/transfer.ts +++ b/src/actions/solana/transfer.ts @@ -1,8 +1,8 @@ import { PublicKey } from "@solana/web3.js"; -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { transfer } from "../tools"; +import { transfer } from "../../tools"; const transferAction: Action = { name: "TRANSFER", diff --git a/src/actions/stakeWithSolayer.ts b/src/actions/solayer/stakeWithSolayer.ts similarity index 91% rename from src/actions/stakeWithSolayer.ts rename to src/actions/solayer/stakeWithSolayer.ts index ec57944..5095bd7 100644 --- a/src/actions/stakeWithSolayer.ts +++ b/src/actions/solayer/stakeWithSolayer.ts @@ -1,7 +1,7 @@ -import { Action } from "../types/action"; -import { SolanaAgentKit } from "../agent"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; import { z } from "zod"; -import { stakeWithSolayer } from "../tools"; +import { stakeWithSolayer } from "../../tools"; const stakeWithSolayerAction: Action = { name: "STAKE_WITH_SOLAYER", diff --git a/src/agent/index.ts b/src/agent/index.ts index 5651703..25037c9 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -63,7 +63,7 @@ import { fetchPythPriceFeedID, flashOpenTrade, flashCloseTrade, -} from "../tools"; +} from "../tools/"; import { CollectionDeployment, CollectionOptions, @@ -79,7 +79,7 @@ import { import { createCollection, createSingle, -} from "../tools/create_3land_collectible"; +} from "../tools/3land/create_3land_collectible"; import { CreateCollectionOptions, CreateSingleOptions, diff --git a/src/langchain/3land/create_collection.ts b/src/langchain/3land/create_collection.ts new file mode 100644 index 0000000..111dd4c --- /dev/null +++ b/src/langchain/3land/create_collection.ts @@ -0,0 +1,68 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { + CreateCollectionOptions, + StoreInitOptions, +} from "@3land/listings-sdk/dist/types/implementation/implementationTypes"; + +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}) + + Inputs: + privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string + isMainnet (required): defines is the tx takes places in mainnet + collectionSymbol (required): the symbol of the collection + 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 + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + const privateKey = inputFormat.privateKey; + const isMainnet = inputFormat.isMainnet; + + const optionsWithBase58: StoreInitOptions = { + ...(privateKey && { privateKey }), + ...(isMainnet && { isMainnet }), + }; + + const collectionSymbol = inputFormat?.collectionSymbol; + const collectionName = inputFormat?.collectionName; + const collectionDescription = inputFormat?.collectionDescription; + const mainImageUrl = inputFormat?.mainImageUrl; + const coverImageUrl = inputFormat?.coverImageUrl; + + const collectionOpts: CreateCollectionOptions = { + ...(collectionSymbol && { collectionSymbol }), + ...(collectionName && { collectionName }), + ...(collectionDescription && { collectionDescription }), + ...(mainImageUrl && { mainImageUrl }), + ...(coverImageUrl && { coverImageUrl }), + }; + + const tx = await this.solanaKit.create3LandCollection( + optionsWithBase58, + collectionOpts, + ); + return JSON.stringify({ + status: "success", + message: `Created Collection successfully ${tx}`, + transaction: tx, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..25db42e --- /dev/null +++ b/src/langchain/3land/create_single.ts @@ -0,0 +1,91 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { + CreateSingleOptions, + StoreInitOptions, +} from "@3land/listings-sdk/dist/types/implementation/implementationTypes"; + +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 + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + const privateKey = inputFormat.privateKey; + const isMainnet = inputFormat.isMainnet; + + const optionsWithBase58: StoreInitOptions = { + ...(privateKey && { privateKey }), + ...(isMainnet && { isMainnet }), + }; + + const collectionAccount = inputFormat.collectionAccount; + + const itemName = inputFormat?.itemName; + const sellerFee = inputFormat?.sellerFee; + const itemAmount = inputFormat?.itemAmount; + const itemSymbol = inputFormat?.itemSymbol; + const itemDescription = inputFormat?.itemDescription; + const traits = inputFormat?.traits; + const price = inputFormat?.price; + const mainImageUrl = inputFormat?.mainImageUrl; + const coverImageUrl = inputFormat?.coverImageUrl; + const splHash = inputFormat?.splHash; + + const createItemOptions: CreateSingleOptions = { + ...(itemName && { itemName }), + ...(sellerFee && { sellerFee }), + ...(itemAmount && { itemAmount }), + ...(itemSymbol && { itemSymbol }), + ...(itemDescription && { itemDescription }), + ...(traits && { traits }), + ...(price && { price }), + ...(mainImageUrl && { mainImageUrl }), + ...(coverImageUrl && { coverImageUrl }), + ...(splHash && { splHash }), + }; + + 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 JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/3land/index.ts b/src/langchain/3land/index.ts new file mode 100644 index 0000000..2065750 --- /dev/null +++ b/src/langchain/3land/index.ts @@ -0,0 +1,2 @@ +export * from "./create_single"; +export * from "./create_collection"; diff --git a/src/langchain/adrena/close_trade.ts b/src/langchain/adrena/close_trade.ts new file mode 100644 index 0000000..7380e89 --- /dev/null +++ b/src/langchain/adrena/close_trade.ts @@ -0,0 +1,49 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaPerpCloseTradeTool extends Tool { + name = "solana_close_perp_trade"; + description = `This tool can be used to close perpetuals trade ( It uses Adrena Protocol ). + + Inputs ( input is a JSON string ): + tradeMint: string, eg "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" etc. (optional) + price?: number, eg 100 (optional) + side: string, eg: "long" or "short"`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const tx = + parsedInput.side === "long" + ? await this.solanaKit.closePerpTradeLong({ + price: parsedInput.price, + tradeMint: new PublicKey(parsedInput.tradeMint), + }) + : await this.solanaKit.closePerpTradeShort({ + price: parsedInput.price, + tradeMint: new PublicKey(parsedInput.tradeMint), + }); + + return JSON.stringify({ + status: "success", + message: "Perpetual trade closed successfully", + transaction: tx, + price: parsedInput.price, + tradeMint: new PublicKey(parsedInput.tradeMint), + side: parsedInput.side, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/adrena/index.ts b/src/langchain/adrena/index.ts new file mode 100644 index 0000000..8557acf --- /dev/null +++ b/src/langchain/adrena/index.ts @@ -0,0 +1,2 @@ +export * from "./open_trade"; +export * from "./close_trade"; diff --git a/src/langchain/adrena/open_trade.ts b/src/langchain/adrena/open_trade.ts new file mode 100644 index 0000000..18f3ecc --- /dev/null +++ b/src/langchain/adrena/open_trade.ts @@ -0,0 +1,65 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaPerpOpenTradeTool extends Tool { + name = "solana_open_perp_trade"; + description = `This tool can be used to open perpetuals trade ( It uses Adrena Protocol ). + + Inputs ( input is a JSON string ): + collateralAmount: number, eg 1 or 0.01 (required) + collateralMint: string, eg "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn" or "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" etc. (optional) + tradeMint: string, eg "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" etc. (optional) + leverage: number, eg 50000 = x5, 100000 = x10, 1000000 = x100 (optional) + price?: number, eg 100 (optional) + 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); + + const tx = + parsedInput.side === "long" + ? await this.solanaKit.openPerpTradeLong({ + price: parsedInput.price, + collateralAmount: parsedInput.collateralAmount, + collateralMint: new PublicKey(parsedInput.collateralMint), + leverage: parsedInput.leverage, + tradeMint: new PublicKey(parsedInput.tradeMint), + slippage: parsedInput.slippage, + }) + : await this.solanaKit.openPerpTradeLong({ + price: parsedInput.price, + collateralAmount: parsedInput.collateralAmount, + collateralMint: new PublicKey(parsedInput.collateralMint), + leverage: parsedInput.leverage, + tradeMint: new PublicKey(parsedInput.tradeMint), + slippage: parsedInput.slippage, + }); + + return JSON.stringify({ + status: "success", + message: "Perpetual trade opened successfully", + transaction: tx, + 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 JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/agent/create_image.ts b/src/langchain/agent/create_image.ts new file mode 100644 index 0000000..441945d --- /dev/null +++ b/src/langchain/agent/create_image.ts @@ -0,0 +1,38 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { create_image } from "../../tools/agent"; + +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"); + } + } + + protected async _call(input: string): Promise { + try { + this.validateInput(input); + const result = await create_image(this.solanaKit, input.trim()); + + return JSON.stringify({ + status: "success", + message: "Image created successfully", + ...result, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/agent/index.ts b/src/langchain/agent/index.ts new file mode 100644 index 0000000..169b9d4 --- /dev/null +++ b/src/langchain/agent/index.ts @@ -0,0 +1,2 @@ +export * from "./create_image"; +export * from "./wallet_address"; diff --git a/src/langchain/agent/wallet_address.ts b/src/langchain/agent/wallet_address.ts new file mode 100644 index 0000000..402f9f6 --- /dev/null +++ b/src/langchain/agent/wallet_address.ts @@ -0,0 +1,15 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaGetWalletAddressTool extends Tool { + name = "solana_get_wallet_address"; + description = `Get the wallet address of the agent`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(_input: string): Promise { + return this.solanaKit.wallet_address.toString(); + } +} diff --git a/src/langchain/alldomains/get_all_tld.ts b/src/langchain/alldomains/get_all_tld.ts new file mode 100644 index 0000000..b6ee67c --- /dev/null +++ b/src/langchain/alldomains/get_all_tld.ts @@ -0,0 +1,29 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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(); + + return JSON.stringify({ + status: "success", + message: "TLDs fetched successfully", + tlds, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TLDS_ERROR", + }); + } + } +} diff --git a/src/langchain/alldomains/index.ts b/src/langchain/alldomains/index.ts new file mode 100644 index 0000000..f9f025c --- /dev/null +++ b/src/langchain/alldomains/index.ts @@ -0,0 +1,4 @@ +export * from "./resolve_all_domains"; +export * from "./owned_domains"; +export * from "./tld_domains"; +export * from "./get_all_tld"; diff --git a/src/langchain/alldomains/owned_domains.ts b/src/langchain/alldomains/owned_domains.ts new file mode 100644 index 0000000..df7e84d --- /dev/null +++ b/src/langchain/alldomains/owned_domains.ts @@ -0,0 +1,34 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const ownerPubkey = new PublicKey(input.trim()); + const domains = await this.solanaKit.getOwnedAllDomains(ownerPubkey); + + return JSON.stringify({ + status: "success", + message: "Owned domains fetched successfully", + domains, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_OWNED_DOMAINS_ERROR", + }); + } + } +} diff --git a/src/langchain/alldomains/resolve_all_domains.ts b/src/langchain/alldomains/resolve_all_domains.ts new file mode 100644 index 0000000..30e053c --- /dev/null +++ b/src/langchain/alldomains/resolve_all_domains.ts @@ -0,0 +1,42 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + DO NOT use this for .sol domains (use solana_resolve_domain instead). + + Input: + domain: string, eg "mydomain.blink" or "mydomain.bonk" (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const owner = await this.solanaKit.resolveAllDomains(input); + + if (!owner) { + return JSON.stringify({ + status: "error", + message: "Domain not found", + code: "DOMAIN_NOT_FOUND", + }); + } + + return JSON.stringify({ + status: "success", + message: "Domain resolved successfully", + owner: owner?.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "DOMAIN_RESOLUTION_ERROR", + }); + } + } +} diff --git a/src/langchain/alldomains/tld_domains.ts b/src/langchain/alldomains/tld_domains.ts new file mode 100644 index 0000000..b3707dd --- /dev/null +++ b/src/langchain/alldomains/tld_domains.ts @@ -0,0 +1,32 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const domains = await this.solanaKit.getOwnedDomainsForTLD(input); + + return JSON.stringify({ + status: "success", + message: "TLD domains fetched successfully", + domains, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TLD_DOMAINS_ERROR", + }); + } + } +} diff --git a/src/langchain/dexscreener/index.ts b/src/langchain/dexscreener/index.ts new file mode 100644 index 0000000..0aace32 --- /dev/null +++ b/src/langchain/dexscreener/index.ts @@ -0,0 +1 @@ +export * from "./token_data_ticker"; diff --git a/src/langchain/dexscreener/token_data_ticker.ts b/src/langchain/dexscreener/token_data_ticker.ts new file mode 100644 index 0000000..88d8a6d --- /dev/null +++ b/src/langchain/dexscreener/token_data_ticker.ts @@ -0,0 +1,31 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 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 new file mode 100644 index 0000000..c671bb1 --- /dev/null +++ b/src/langchain/flash/flash_close.ts @@ -0,0 +1,53 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaFlashCloseTrade extends Tool { + name = "solana_flash_close_trade"; + description = `Close an existing leveraged trading position on Flash.Trade exchange. + + Inputs ( input is a JSON string ): + token: string, eg "SOL", "BTC", "ETH" (required) + side: string, eg "long", "short" (required) + + 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 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: parsedInput.token, + side: parsedInput.side, + }); + + return JSON.stringify({ + status: "success", + message: "Flash trade position closed successfully", + transaction: tx, + token: parsedInput.token, + side: parsedInput.side, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..e35a966 --- /dev/null +++ b/src/langchain/flash/flash_open.ts @@ -0,0 +1,81 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { marketTokenMap } from "../../utils/flashUtils"; + +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. + + Inputs ( input is a JSON string ): + token: string, eg "SOL", "BTC", "ETH" (required) + type: string, eg "long", "short" (required) + collateral: number, eg 10, 100, 1000 (required) + leverage: number, eg 5, 10, 20 (required) + + 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 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: 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: parsedInput.token, + side: parsedInput.type, + collateral: parsedInput.collateral, + leverage: parsedInput.leverage, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..da6243e --- /dev/null +++ b/src/langchain/flash/index.ts @@ -0,0 +1,2 @@ +export * from "./flash_open"; +export * from "./flash_close"; diff --git a/src/langchain/gibwork/create_task.ts b/src/langchain/gibwork/create_task.ts new file mode 100644 index 0000000..c7af778 --- /dev/null +++ b/src/langchain/gibwork/create_task.ts @@ -0,0 +1,52 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { GibworkCreateTaskReponse } from "../../index"; + +export class SolanaCreateGibworkTask extends Tool { + name = "create_gibwork_task"; + description = `Create a task on Gibwork. + + Inputs (input is a JSON string): + title: string, title of the task (required) + content: string, description of the task (required) + requirements: string, requirements to complete the task (required) + 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) + `; + + constructor(private solanaSdk: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const taskData = await this.solanaSdk.createGibworkTask( + parsedInput.title, + parsedInput.content, + parsedInput.requirements, + parsedInput.tags, + parsedInput.tokenMintAddress, + parsedInput.amount, + parsedInput.payer, + ); + + const response: GibworkCreateTaskReponse = { + status: "success", + taskId: taskData.taskId, + signature: taskData.signature, + }; + + 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 new file mode 100644 index 0000000..34d0b3b --- /dev/null +++ b/src/langchain/gibwork/index.ts @@ -0,0 +1 @@ +export * from "./create_task"; diff --git a/src/langchain/index.ts b/src/langchain/index.ts index e442206..c2e5aff 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -1,2692 +1,89 @@ -import { PublicKey } from "@solana/web3.js"; -import { BN } from "@coral-xyz/anchor"; -import Decimal from "decimal.js"; -import { Tool } from "langchain/tools"; +export * from "./adrena"; +export * from "./alldomains"; +export * from "./dexscreener"; +export * from "./alldomains"; +export * from "./flash"; +export * from "./gibwork"; +export * from "./jupiter"; +export * from "./lulo"; +export * from "./manifest"; +export * from "./solana"; +export * from "./agent"; +export * from "./metaplex"; +export * from "./openbook"; +export * from "./orca"; +export * from "./pumpfun"; +export * from "./pyth"; +export * from "./raydium"; +export * from "./rugcheck"; +export * from "./sendarcade"; +export * from "./solayer"; +export * from "./tensor"; +export * from "./3land"; +export * from "./tiplink"; +export * from "./sns"; +export * from "./lightprotocol"; + +import { SolanaAgentKit } from "../agent"; import { - GibworkCreateTaskReponse, - OrderParams, - PythFetchPriceResponse, - SolanaAgentKit, -} from "../index"; -import { create_image, FEE_TIERS, generateOrdersfromPattern } from "../tools"; -import { marketTokenMap } from "../utils/flashUtils"; -import { - CreateCollectionOptions, - CreateSingleOptions, - StoreInitOptions, -} from "@3land/listings-sdk/dist/types/implementation/implementationTypes"; - -export class SolanaBalanceTool extends Tool { - name = "solana_balance"; - description = `Get the balance of a Solana wallet or token account. - - If you want to get the balance of your wallet, you don't need to provide the tokenAddress. - If no tokenAddress is provided, the balance will be in SOL. - - Inputs ( input is a JSON string ): - tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const tokenAddress = input ? new PublicKey(input) : undefined; - const balance = await this.solanaKit.getBalance(tokenAddress); - - return JSON.stringify({ - status: "success", - balance, - token: input || "SOL", - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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. - - If no tokenAddress is provided, the SOL balance of the wallet will be returned. - - Inputs ( input is a JSON string ): - walletAddress: string, eg "GDEkQF7UMr7RLv1KQKMtm8E2w3iafxJLtyXu3HVQZnME" (required) - tokenAddress: string, eg "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const { walletAddress, tokenAddress } = JSON.parse(input); - - const tokenPubKey = tokenAddress - ? new PublicKey(tokenAddress) - : undefined; - - const balance = await this.solanaKit.getBalanceOther( - new PublicKey(walletAddress), - tokenPubKey, - ); - - return JSON.stringify({ - status: "success", - balance, - wallet: walletAddress, - token: tokenAddress || "SOL", - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaTransferTool extends Tool { - name = "solana_transfer"; - description = `Transfer tokens or SOL to another address ( also called as wallet address ). - - Inputs ( input is a JSON string ): - to: string, eg "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk" (required) - 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 parsedInput = JSON.parse(input); - - const recipient = new PublicKey(parsedInput.to); - const mintAddress = parsedInput.mint - ? new PublicKey(parsedInput.mint) - : undefined; - - const tx = await this.solanaKit.transfer( - recipient, - parsedInput.amount, - mintAddress, - ); - - return JSON.stringify({ - status: "success", - message: "Transfer completed successfully", - amount: parsedInput.amount, - recipient: parsedInput.to, - token: parsedInput.mint || "SOL", - transaction: tx, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaDeployTokenTool extends Tool { - name = "solana_deploy_token"; - description = `Deploy a new token on Solana blockchain. - - Inputs (input is a JSON string): - name: string, eg "My Token" (required) - uri: string, eg "https://example.com/token.json" (required) - symbol: string, eg "MTK" (required) - 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 parsedInput = JSON.parse(input); - - const result = await this.solanaKit.deployToken( - parsedInput.name, - parsedInput.uri, - parsedInput.symbol, - parsedInput.decimals, - parsedInput.initialSupply, - ); - - return JSON.stringify({ - status: "success", - message: "Token deployed successfully", - mintAddress: result.mint.toString(), - decimals: parsedInput.decimals || 9, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - - const result = await this.solanaKit.deployCollection(parsedInput); - - return JSON.stringify({ - status: "success", - message: "Collection deployed successfully", - collectionAddress: result.collectionAddress.toString(), - name: parsedInput.name, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaMintNFTTool extends Tool { - name = "solana_mint_nft"; - description = `Mint a new NFT in a collection on Solana blockchain. - - Inputs (input is a JSON string): - 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 which is ${this.solanaKit.wallet_address.toString()}`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - - const result = await this.solanaKit.mintNFT( - new PublicKey(parsedInput.collectionMint), - { - name: parsedInput.name, - uri: parsedInput.uri, - }, - parsedInput.recipient - ? new PublicKey(parsedInput.recipient) - : this.solanaKit.wallet_address, - ); - - return JSON.stringify({ - status: "success", - message: "NFT minted successfully", - mintAddress: result.mint.toString(), - metadata: { - name: parsedInput.name, - symbol: parsedInput.symbol, - uri: parsedInput.uri, - }, - recipient: parsedInput.recipient || result.mint.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaPerpCloseTradeTool extends Tool { - name = "solana_close_perp_trade"; - description = `This tool can be used to close perpetuals trade ( It uses Adrena Protocol ). - - Inputs ( input is a JSON string ): - tradeMint: string, eg "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" etc. (optional) - price?: number, eg 100 (optional) - side: string, eg: "long" or "short"`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - - const tx = - parsedInput.side === "long" - ? await this.solanaKit.closePerpTradeLong({ - price: parsedInput.price, - tradeMint: new PublicKey(parsedInput.tradeMint), - }) - : await this.solanaKit.closePerpTradeShort({ - price: parsedInput.price, - tradeMint: new PublicKey(parsedInput.tradeMint), - }); - - return JSON.stringify({ - status: "success", - message: "Perpetual trade closed successfully", - transaction: tx, - price: parsedInput.price, - tradeMint: new PublicKey(parsedInput.tradeMint), - side: parsedInput.side, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaPerpOpenTradeTool extends Tool { - name = "solana_open_perp_trade"; - description = `This tool can be used to open perpetuals trade ( It uses Adrena Protocol ). - - Inputs ( input is a JSON string ): - collateralAmount: number, eg 1 or 0.01 (required) - collateralMint: string, eg "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn" or "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" etc. (optional) - tradeMint: string, eg "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn", "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" etc. (optional) - leverage: number, eg 50000 = x5, 100000 = x10, 1000000 = x100 (optional) - price?: number, eg 100 (optional) - 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); - - const tx = - parsedInput.side === "long" - ? await this.solanaKit.openPerpTradeLong({ - price: parsedInput.price, - collateralAmount: parsedInput.collateralAmount, - collateralMint: new PublicKey(parsedInput.collateralMint), - leverage: parsedInput.leverage, - tradeMint: new PublicKey(parsedInput.tradeMint), - slippage: parsedInput.slippage, - }) - : await this.solanaKit.openPerpTradeLong({ - price: parsedInput.price, - collateralAmount: parsedInput.collateralAmount, - collateralMint: new PublicKey(parsedInput.collateralMint), - leverage: parsedInput.leverage, - tradeMint: new PublicKey(parsedInput.tradeMint), - slippage: parsedInput.slippage, - }); - - return JSON.stringify({ - status: "success", - message: "Perpetual trade opened successfully", - transaction: tx, - 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 JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - - const tx = await this.solanaKit.trade( - new PublicKey(parsedInput.outputMint), - parsedInput.inputAmount, - parsedInput.inputMint - ? new PublicKey(parsedInput.inputMint) - : new PublicKey("So11111111111111111111111111111111111111112"), - parsedInput.slippageBps, - ); - - return JSON.stringify({ - status: "success", - message: "Trade executed successfully", - transaction: tx, - inputAmount: parsedInput.inputAmount, - inputToken: parsedInput.inputMint || "SOL", - outputToken: parsedInput.outputMint, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - - const tx = await this.solanaKit.limitOrder( - new PublicKey(parsedInput.marketId), - parsedInput.quantity, - parsedInput.side, - parsedInput.price, - ); - - return JSON.stringify({ - status: "success", - message: "Trade executed successfully", - transaction: tx, - marketId: parsedInput.marketId, - quantity: parsedInput.quantity, - side: parsedInput.side, - price: parsedInput.price, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 } - ] - } - - 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.`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - let ordersToPlace: OrderParams[] = []; - - if (!parsedInput.marketId) { - throw new Error("Market ID is required"); - } - - if (parsedInput.pattern) { - ordersToPlace = generateOrdersfromPattern(parsedInput.pattern); - } else if (Array.isArray(parsedInput.orders)) { - ordersToPlace = parsedInput.orders; - } else { - throw new Error("Either pattern or orders array is required"); - } - - if (ordersToPlace.length === 0) { - throw new Error("No orders generated or provided"); - } - - ordersToPlace.forEach((order: OrderParams, index: number) => { - if (!order.quantity || !order.side || !order.price) { - throw new Error( - `Invalid order at index ${index}: quantity, side, and price are required`, - ); - } - if (order.side !== "Buy" && order.side !== "Sell") { - throw new Error( - `Invalid side at index ${index}: must be "Buy" or "Sell"`, - ); - } - }); - - const tx = await this.solanaKit.batchOrder( - new PublicKey(parsedInput.marketId), - parsedInput.orders, - ); - - return JSON.stringify({ - status: "success", - message: "Batch order executed successfully", - transaction: tx, - marketId: parsedInput.marketId, - orders: parsedInput.orders, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const marketId = new PublicKey(input.trim()); - const tx = await this.solanaKit.cancelAllOrders(marketId); - - return JSON.stringify({ - status: "success", - message: "Cancel orders successfully", - transaction: tx, - marketId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const marketId = new PublicKey(input.trim()); - const tx = await this.solanaKit.withdrawAll(marketId); - - return JSON.stringify({ - status: "success", - message: "Withdrew successfully", - transaction: tx, - marketId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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(); - - return JSON.stringify({ - status: "success", - message: "Successfully requested faucet funds", - network: this.solanaKit.connection.rpcEndpoint.split("/")[2], - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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) - `; - - 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 parsedInput = JSON.parse(input); - this.validateInput(parsedInput); - - const tx = await this.solanaKit.registerDomain( - parsedInput.name, - parsedInput.spaceKB || 1, - ); - - return JSON.stringify({ - status: "success", - message: "Domain registered successfully", - transaction: tx, - domain: `${parsedInput.name}.sol`, - spaceKB: parsedInput.spaceKB || 1, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const domain = input.trim(); - const publicKey = await this.solanaKit.resolveSolDomain(domain); - - return JSON.stringify({ - status: "success", - message: "Domain resolved successfully", - publicKey: publicKey.toBase58(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const account = new PublicKey(input.trim()); - const domain = await this.solanaKit.getPrimaryDomain(account); - - return JSON.stringify({ - status: "success", - message: "Primary domain retrieved successfully", - domain, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaGetWalletAddressTool extends Tool { - name = "solana_get_wallet_address"; - description = `Get the wallet address of the agent`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(_input: string): Promise { - return this.solanaKit.wallet_address.toString(); - } -} - -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. - - Inputs ( input is a JSON string ): - token: string, eg "SOL", "BTC", "ETH" (required) - type: string, eg "long", "short" (required) - collateral: number, eg 10, 100, 1000 (required) - leverage: number, eg 5, 10, 20 (required) - - 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 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: 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: parsedInput.token, - side: parsedInput.type, - collateral: parsedInput.collateral, - leverage: parsedInput.leverage, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaFlashCloseTrade extends Tool { - name = "solana_flash_close_trade"; - description = `Close an existing leveraged trading position on Flash.Trade exchange. - - Inputs ( input is a JSON string ): - token: string, eg "SOL", "BTC", "ETH" (required) - side: string, eg "long", "short" (required) - - 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 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: parsedInput.token, - side: parsedInput.side, - }); - - return JSON.stringify({ - status: "success", - message: "Flash trade position closed successfully", - transaction: tx, - token: parsedInput.token, - side: parsedInput.side, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaPumpfunTokenLaunchTool extends Tool { - name = "solana_launch_pumpfun_token"; - - description = `This tool can be used to launch a token on Pump.fun, - do not use this tool for any other purpose, or for creating SPL tokens. - If the user asks you to chose the parameters, you should generate valid values. - For generating the image, you can use the solana_create_image tool. - - Inputs: - tokenName: string, eg "PumpFun Token", - tokenTicker: string, eg "PUMP", - 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"); - } - if (!input.tokenTicker || typeof input.tokenTicker !== "string") { - throw new Error("tokenTicker is required and must be a string"); - } - if (!input.description || typeof input.description !== "string") { - throw new Error("description is required and must be a string"); - } - if (!input.imageUrl || typeof input.imageUrl !== "string") { - throw new Error("imageUrl is required and must be a string"); - } - if ( - input.initialLiquiditySOL !== undefined && - typeof input.initialLiquiditySOL !== "number" - ) { - throw new Error("initialLiquiditySOL must be a number when provided"); - } - } - - protected async _call(input: string): Promise { - try { - // Parse and normalize input - input = input.trim(); - const parsedInput = JSON.parse(input); - - this.validateInput(parsedInput); - - // Launch token with validated input - await this.solanaKit.launchPumpFunToken( - parsedInput.tokenName, - parsedInput.tokenTicker, - parsedInput.description, - parsedInput.imageUrl, - { - twitter: parsedInput.twitter, - telegram: parsedInput.telegram, - website: parsedInput.website, - initialLiquiditySOL: parsedInput.initialLiquiditySOL, - }, - ); - - return JSON.stringify({ - status: "success", - message: "Token launched successfully on Pump.fun", - tokenName: parsedInput.tokenName, - tokenTicker: parsedInput.tokenTicker, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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"); - } - } - - protected async _call(input: string): Promise { - try { - this.validateInput(input); - const result = await create_image(this.solanaKit, input.trim()); - - return JSON.stringify({ - status: "success", - message: "Image created successfully", - ...result, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 { - const amount = JSON.parse(input).amount || input; - - const tx = await this.solanaKit.lendAssets(amount); - - return JSON.stringify({ - status: "success", - message: "Asset lent successfully", - transaction: tx, - amount, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 `Solana (mainnet-beta) current transactions per second: ${tps}`; - } catch (error: any) { - return `Error fetching TPS: ${error.message}`; - } - } -} - -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); - - const tx = await this.solanaKit.stake(parsedInput.amount); - - return JSON.stringify({ - status: "success", - message: "Staked successfully", - transaction: tx, - amount: parsedInput.amount, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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); - - const tx = await this.solanaKit.restake(parsedInput.amount); - - return JSON.stringify({ - status: "success", - message: "Staked successfully", - transaction: tx, - amount: parsedInput.amount, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -/** - * Tool to fetch the price of a token in USDC - */ -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()); - return JSON.stringify({ - status: "success", - tokenId: input.trim(), - priceInUSDC: price, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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({ - status: "success", - tokenData, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaCompressedAirdropTool extends Tool { - name = "solana_compressed_airdrop"; - description = `Airdrop SPL tokens with ZK Compression (also called as airdropping tokens) - - Inputs (input is a JSON string): - mintAddress: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required) - amount: number, the amount of tokens to airdrop per recipient, e.g., 42 (required) - decimals: number, the decimals of the token, e.g., 6 (required) - recipients: string[], the recipient addresses, e.g., ["1nc1nerator11111111111111111111111111111111"] (required) - 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 parsedInput = JSON.parse(input); - - const txs = await this.solanaKit.sendCompressedAirdrop( - parsedInput.mintAddress, - parsedInput.amount, - parsedInput.decimals, - parsedInput.recipients, - parsedInput.priorityFeeInLamports || 30_000, - parsedInput.shouldLog || false, - ); - - return JSON.stringify({ - status: "success", - message: `Airdropped ${parsedInput.amount} tokens to ${parsedInput.recipients.length} recipients.`, - transactionHashes: txs, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaClosePosition extends Tool { - name = "orca_close_position"; - description = `Closes an existing liquidity position in an Orca Whirlpool. This function fetches the position - details using the provided mint address and closes the position with a 1% slippage. - - Inputs (JSON string): - - positionMintAddress: string, the address of the position mint that represents the liquidity position.`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - 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, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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. - - Inputs (JSON string): - - mintDeploy: string, the mint of the token you want to deploy (required). - - mintPair: string, The mint of the token you want to pair the deployed mint with (required). - - 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 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( - `Invalid feeTier. Available options: ${Object.keys(FEE_TIERS).join( - ", ", - )}`, - ); - } - - const txId = await this.solanaKit.orcaCreateCLMM( - mintA, - mintB, - initialPrice, - feeTier, - ); - - return JSON.stringify({ - status: "success", - message: - "CLMM pool created successfully. Note: No liquidity was added.", - transaction: txId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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. - - This function initializes a single-sided liquidity pool, ideal for community driven project, fair launches, and fundraising. Minimize price impact by setting a narrow price range. - - Inputs (JSON string): - - depositTokenAmount: number, in units of the deposit token including decimals, e.g., 1000000000 (required). - - depositTokenMint: string, mint address of the deposit token, e.g., "DepositTokenMintAddress" (required). - - otherTokenMint: string, mint address of the other token, e.g., "OtherTokenMintAddress" (required). - - initialPrice: number, initial price of the deposit token in terms of the other token, e.g., 0.001 (required). - - 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 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( - `Invalid feeTier. Available options: ${Object.keys(FEE_TIERS).join( - ", ", - )}`, - ); - } - - const txId = await this.solanaKit.orcaCreateSingleSidedLiquidityPool( - depositTokenAmount, - depositTokenMint, - otherTokenMint, - initialPrice, - maxPrice, - feeTier, - ); - - return JSON.stringify({ - status: "success", - message: "Single-sided Whirlpool created successfully", - transaction: txId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 positiont mint addresses as keys and position status details as values.`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(): Promise { - try { - const txId = await this.solanaKit.orcaFetchPositions(); - - return JSON.stringify({ - status: "success", - message: "Liquidity positions fetched.", - transaction: txId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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. - - Inputs (JSON string): - - whirlpoolAddress: string, address of the Orca Whirlpool (required). - - priceOffsetBps: number, bps offset (one side) from the current pool price, e.g., 500 for 5% (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 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( - whirlpoolAddress, - priceOffsetBps, - inputTokenMint, - inputAmount, - ); - - return JSON.stringify({ - status: "success", - message: "Centered liquidity position opened successfully.", - transaction: txId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 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 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( - whirlpoolAddress, - distanceFromCurrentPriceBps, - widthBps, - inputTokenMint, - inputAmount, - ); - - return JSON.stringify({ - status: "success", - message: "Single-sided liquidity position opened successfully.", - transaction: txId, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaRaydiumCreateAmmV4 extends Tool { - name = "raydium_create_ammV4"; - description = `Raydium's Legacy AMM that requires an OpenBook marketID - - Inputs (input is a json string): - marketId: string (required) - baseAmount: number(int), eg: 111111 (required) - quoteAmount: number(int), eg: 111111 (required) - startTime: number(seconds), eg: now number or zero (required) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - - const tx = await this.solanaKit.raydiumCreateAmmV4( - new PublicKey(inputFormat.marketId), - new BN(inputFormat.baseAmount), - new BN(inputFormat.quoteAmount), - new BN(inputFormat.startTime), - ); - - return JSON.stringify({ - status: "success", - message: "Raydium amm v4 pool created successfully", - transaction: tx, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaRaydiumCreateClmm extends Tool { - name = "raydium_create_clmm"; - description = `Concentrated liquidity market maker, custom liquidity ranges, increased capital efficiency - - Inputs (input is a json string): - mint1: string (required) - 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) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - - const tx = await this.solanaKit.raydiumCreateClmm( - new PublicKey(inputFormat.mint1), - new PublicKey(inputFormat.mint2), - - new PublicKey(inputFormat.configId), - - new Decimal(inputFormat.initialPrice), - new BN(inputFormat.startTime), - ); - - return JSON.stringify({ - status: "success", - message: "Raydium clmm pool created successfully", - transaction: tx, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaRaydiumCreateCpmm extends Tool { - name = "raydium_create_cpmm"; - description = `Raydium's newest CPMM, does not require marketID, supports Token 2022 standard - - Inputs (input is a json string): - mint1: string (required) - mint2: string (required) - 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) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - - const tx = await this.solanaKit.raydiumCreateCpmm( - 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({ - status: "success", - message: "Raydium cpmm pool created successfully", - transaction: tx, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaOpenbookCreateMarket extends Tool { - name = "solana_openbook_create_market"; - description = `Openbook marketId, required for ammv4 - - Inputs (input is a json string): - baseMint: string (required) - quoteMint: string (required) - lotSize: number (required) - tickSize: number (required) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - - const tx = await this.solanaKit.openbookCreateMarket( - new PublicKey(inputFormat.baseMint), - new PublicKey(inputFormat.quoteMint), - - inputFormat.lotSize, - inputFormat.tickSize, - ); - - return JSON.stringify({ - status: "success", - message: "Openbook market created successfully", - transaction: tx, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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) - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - - const tx = await this.solanaKit.manifestCreateMarket( - new PublicKey(inputFormat.baseMint), - new PublicKey(inputFormat.quoteMint), - ); - - return JSON.stringify({ - status: "success", - message: "Create manifest market successfully", - transaction: tx[0], - marketId: tx[1], - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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: PythFetchPriceResponse = { - status: "success", - tokenSymbol: input, - priceFeedID, - price, - }; - - return JSON.stringify(response); - } catch (error: any) { - const response: PythFetchPriceResponse = { - status: "error", - tokenSymbol: input, - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }; - return JSON.stringify(response); - } - } -} - -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. - DO NOT use this for .sol domains (use solana_resolve_domain instead). - - Input: - domain: string, eg "mydomain.blink" or "mydomain.bonk" (required)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const owner = await this.solanaKit.resolveAllDomains(input); - - if (!owner) { - return JSON.stringify({ - status: "error", - message: "Domain not found", - code: "DOMAIN_NOT_FOUND", - }); - } - - return JSON.stringify({ - status: "success", - message: "Domain resolved successfully", - owner: owner?.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "DOMAIN_RESOLUTION_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const ownerPubkey = new PublicKey(input.trim()); - const domains = await this.solanaKit.getOwnedAllDomains(ownerPubkey); - - return JSON.stringify({ - status: "success", - message: "Owned domains fetched successfully", - domains, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "FETCH_OWNED_DOMAINS_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const domains = await this.solanaKit.getOwnedDomainsForTLD(input); - - return JSON.stringify({ - status: "success", - message: "TLD domains fetched successfully", - domains, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "FETCH_TLD_DOMAINS_ERROR", - }); - } - } -} - -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(); - - return JSON.stringify({ - status: "success", - message: "TLDs fetched successfully", - tlds, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "FETCH_TLDS_ERROR", - }); - } - } -} - -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)`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - async _call(input: string): Promise { - try { - const ownerPubkey = new PublicKey(input.trim()); - const mainDomain = - await this.solanaKit.getMainAllDomainsDomain(ownerPubkey); - - return JSON.stringify({ - status: "success", - message: "Main domain fetched successfully", - domain: mainDomain, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "FETCH_MAIN_DOMAIN_ERROR", - }); - } - } -} - -export class SolanaCreateGibworkTask extends Tool { - name = "create_gibwork_task"; - description = `Create a task on Gibwork. - - Inputs (input is a JSON string): - title: string, title of the task (required) - content: string, description of the task (required) - requirements: string, requirements to complete the task (required) - 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) - `; - - constructor(private solanaSdk: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const parsedInput = JSON.parse(input); - - const taskData = await this.solanaSdk.createGibworkTask( - parsedInput.title, - parsedInput.content, - parsedInput.requirements, - parsedInput.tags, - parsedInput.tokenMintAddress, - parsedInput.amount, - parsedInput.payer, - ); - - const response: GibworkCreateTaskReponse = { - status: "success", - taskId: taskData.taskId, - signature: taskData.signature, - }; - - return JSON.stringify(response); - } catch (err: any) { - return JSON.stringify({ - status: "error", - message: err.message, - code: err.code || "CREATE_TASK_ERROR", - }); - } - } -} - -export class SolanaRockPaperScissorsTool extends Tool { - name = "rock_paper_scissors"; - description = `Play rock paper scissors to win SEND coins. - - Inputs (input is a JSON string): - 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 parsedInput = JSON.parse(input); - this.validateInput(parsedInput); - const result = await this.solanaKit.rockPaperScissors( - Number(parsedInput['"amount"']), - parsedInput['"choice"'].replace(/^"|"$/g, "") as - | "rock" - | "paper" - | "scissors", - ); - - return JSON.stringify({ - status: "success", - message: result, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 parsedInput = JSON.parse(input); - - if (!parsedInput.amount) { - throw new Error("Amount is required"); - } - - const amount = parseFloat(parsedInput.amount); - const splmintAddress = parsedInput.splmintAddress - ? new PublicKey(parsedInput.splmintAddress) - : undefined; - - const { url, signature } = await this.solanaKit.createTiplink( - amount, - splmintAddress, - ); - - return JSON.stringify({ - status: "success", - url, - signature, - amount, - tokenType: splmintAddress ? "SPL" : "SOL", - message: `TipLink created successfully`, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaListNFTForSaleTool extends Tool { - name = "solana_list_nft_for_sale"; - description = `List an NFT for sale on Tensor Trade. - - Inputs (input is a JSON string): - 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 parsedInput = JSON.parse(input); - - // Validate NFT ownership first - const nftAccount = - await this.solanaKit.connection.getTokenAccountsByOwner( - this.solanaKit.wallet_address, - { mint: new PublicKey(parsedInput.nftMint) }, - ); - - if (nftAccount.value.length === 0) { - return JSON.stringify({ - status: "error", - message: - "NFT not found in wallet. Please make sure you own this NFT.", - code: "NFT_NOT_FOUND", - }); - } - - const tx = await this.solanaKit.tensorListNFT( - new PublicKey(parsedInput.nftMint), - parsedInput.price, - ); - - return JSON.stringify({ - status: "success", - message: "NFT listed for sale successfully", - transaction: tx, - price: parsedInput.price, - nftMint: parsedInput.nftMint, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 parsedInput = JSON.parse(input); - - const tx = await this.solanaKit.tensorCancelListing( - new PublicKey(parsedInput.nftMint), - ); - - return JSON.stringify({ - status: "success", - message: "NFT listing cancelled successfully", - transaction: tx, - nftMint: parsedInput.nftMint, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -export class SolanaFetchTokenReportSummaryTool extends Tool { - name = "solana_fetch_token_report_summary"; - description = `Fetches a summary report for a specific token from RugCheck. - Inputs: - - mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const mint = input.trim(); - const report = await this.solanaKit.fetchTokenReportSummary(mint); - - return JSON.stringify({ - status: "success", - message: "Token report summary fetched successfully", - report, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "FETCH_TOKEN_REPORT_SUMMARY_ERROR", - }); - } - } -} - -export class SolanaFetchTokenDetailedReportTool extends Tool { - name = "solana_fetch_token_detailed_report"; - description = `Fetches a detailed report for a specific token from RugCheck. - Inputs: - - mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const mint = input.trim(); - const detailedReport = - await this.solanaKit.fetchTokenDetailedReport(mint); - - return JSON.stringify({ - status: "success", - message: "Detailed token report fetched successfully", - report: detailedReport, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "FETCH_TOKEN_DETAILED_REPORT_ERROR", - }); - } - } -} - -export 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 - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - const privateKey = inputFormat.privateKey; - const isMainnet = inputFormat.isMainnet; - - const optionsWithBase58: StoreInitOptions = { - ...(privateKey && { privateKey }), - ...(isMainnet && { isMainnet }), - }; - - const collectionAccount = inputFormat.collectionAccount; - - const itemName = inputFormat?.itemName; - const sellerFee = inputFormat?.sellerFee; - const itemAmount = inputFormat?.itemAmount; - const itemSymbol = inputFormat?.itemSymbol; - const itemDescription = inputFormat?.itemDescription; - const traits = inputFormat?.traits; - const price = inputFormat?.price; - const mainImageUrl = inputFormat?.mainImageUrl; - const coverImageUrl = inputFormat?.coverImageUrl; - const splHash = inputFormat?.splHash; - - const createItemOptions: CreateSingleOptions = { - ...(itemName && { itemName }), - ...(sellerFee && { sellerFee }), - ...(itemAmount && { itemAmount }), - ...(itemSymbol && { itemSymbol }), - ...(itemDescription && { itemDescription }), - ...(traits && { traits }), - ...(price && { price }), - ...(mainImageUrl && { mainImageUrl }), - ...(coverImageUrl && { coverImageUrl }), - ...(splHash && { splHash }), - }; - - 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 JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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}) - - Inputs: - privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string - isMainnet (required): defines is the tx takes places in mainnet - collectionSymbol (required): the symbol of the collection - 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 - `; - - constructor(private solanaKit: SolanaAgentKit) { - super(); - } - - protected async _call(input: string): Promise { - try { - const inputFormat = JSON.parse(input); - const privateKey = inputFormat.privateKey; - const isMainnet = inputFormat.isMainnet; - - const optionsWithBase58: StoreInitOptions = { - ...(privateKey && { privateKey }), - ...(isMainnet && { isMainnet }), - }; - - const collectionSymbol = inputFormat?.collectionSymbol; - const collectionName = inputFormat?.collectionName; - const collectionDescription = inputFormat?.collectionDescription; - const mainImageUrl = inputFormat?.mainImageUrl; - const coverImageUrl = inputFormat?.coverImageUrl; - - const collectionOpts: CreateCollectionOptions = { - ...(collectionSymbol && { collectionSymbol }), - ...(collectionName && { collectionName }), - ...(collectionDescription && { collectionDescription }), - ...(mainImageUrl && { mainImageUrl }), - ...(coverImageUrl && { coverImageUrl }), - }; - - const tx = await this.solanaKit.create3LandCollection( - optionsWithBase58, - collectionOpts, - ); - return JSON.stringify({ - status: "success", - message: `Created Collection successfully ${tx}`, - transaction: tx, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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 } = - await this.solanaKit.closeEmptyTokenAccounts(); - - return JSON.stringify({ - 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, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "UNKNOWN_ERROR", - }); - } - } -} - -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. - - Note: For one AI agent, only one 2-by-2 multisig can be created as it is pair-wise. - - 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); - const creator = new PublicKey(inputFormat.creator); - - const multisig = await this.solanaKit.createSquadsMultisig(creator); - - return JSON.stringify({ - status: "success", - message: "2-by-2 multisig account created successfully", - multisig, - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "CREATE_2BY2_MULTISIG_ERROR", - }); - } - } -} - -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); - const amount = new Decimal(inputFormat.amount); - - const tx = await this.solanaKit.depositToMultisig(amount.toNumber()); - - return JSON.stringify({ - status: "success", - message: "Funds deposited to 2-by-2 multisig account successfully", - transaction: tx, - amount: amount.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "DEPOSIT_TO_2BY2_MULTISIG_ERROR", - }); - } - } -} - -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. - - Inputs (JSON string): - - 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); - const amount = new Decimal(inputFormat.amount); - const recipient = new PublicKey(inputFormat.recipient); - - const tx = await this.solanaKit.transferFromMultisig( - amount.toNumber(), - recipient, - ); - - return JSON.stringify({ - status: "success", - message: "Transaction added to 2-by-2 multisig account successfully", - transaction: tx, - amount: amount.toString(), - recipient: recipient.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "TRANSFER_FROM_2BY2_MULTISIG_ERROR", - }); - } - } -} - -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. - - If transactionIndex is not provided, the latest index will automatically be fetched and used. - - 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); - const transactionIndex = inputFormat.transactionIndex ?? undefined; - - const tx = await this.solanaKit.createMultisigProposal(transactionIndex); - - return JSON.stringify({ - status: "success", - message: "Proposal created successfully", - transaction: tx, - transactionIndex: transactionIndex?.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "CREATE_PROPOSAL_2BY2_MULTISIG_ERROR", - }); - } - } -} - -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. - - If proposalIndex is not provided, the latest index will automatically be fetched and used. - - 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); - const proposalIndex = inputFormat.proposalIndex ?? undefined; - - const tx = await this.solanaKit.approveMultisigProposal(proposalIndex); - - return JSON.stringify({ - status: "success", - message: "Proposal approved successfully", - transaction: tx, - proposalIndex: proposalIndex.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "APPROVE_PROPOSAL_2BY2_MULTISIG_ERROR", - }); - } - } -} - -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. - - If proposalIndex is not provided, the latest index will automatically be fetched and used. - - 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); - const proposalIndex = inputFormat.proposalIndex ?? undefined; - - const tx = await this.solanaKit.rejectMultisigProposal(proposalIndex); - - return JSON.stringify({ - status: "success", - message: "Proposal rejected successfully", - transaction: tx, - proposalIndex: proposalIndex.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "REJECT_PROPOSAL_2BY2_MULTISIG_ERROR", - }); - } - } -} - -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. - - If proposalIndex is not provided, the latest index will automatically be fetched and used. - - 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); - const proposalIndex = inputFormat.proposalIndex ?? undefined; - - const tx = await this.solanaKit.executeMultisigTransaction(proposalIndex); - - return JSON.stringify({ - status: "success", - message: "Proposal executed successfully", - transaction: tx, - proposalIndex: proposalIndex.toString(), - }); - } catch (error: any) { - return JSON.stringify({ - status: "error", - message: error.message, - code: error.code || "EXECUTE_PROPOSAL_2BY2_MULTISIG_ERROR", - }); - } - } -} + SolanaBalanceTool, + SolanaBalanceOtherTool, + SolanaTransferTool, + SolanaDeployTokenTool, + SolanaDeployCollectionTool, + SolanaMintNFTTool, + SolanaTradeTool, + SolanaRequestFundsTool, + SolanaRegisterDomainTool, + SolanaGetWalletAddressTool, + SolanaPumpfunTokenLaunchTool, + SolanaCreateImageTool, + SolanaLendAssetTool, + SolanaTPSCalculatorTool, + SolanaStakeTool, + SolanaRestakeTool, + SolanaFetchPriceTool, + SolanaGetDomainTool, + SolanaTokenDataTool, + SolanaTokenDataByTickerTool, + SolanaCompressedAirdropTool, + SolanaRaydiumCreateAmmV4, + SolanaRaydiumCreateClmm, + SolanaRaydiumCreateCpmm, + SolanaOpenbookCreateMarket, + SolanaManifestCreateMarket, + SolanaLimitOrderTool, + SolanaBatchOrderTool, + SolanaCancelAllOrdersTool, + SolanaWithdrawAllTool, + SolanaClosePosition, + SolanaOrcaCreateCLMM, + SolanaOrcaCreateSingleSideLiquidityPool, + SolanaOrcaFetchPositions, + SolanaOrcaOpenCenteredPosition, + SolanaOrcaOpenSingleSidedPosition, + SolanaPythFetchPrice, + SolanaResolveDomainTool, + SolanaGetOwnedDomains, + SolanaGetOwnedTldDomains, + SolanaGetAllTlds, + SolanaGetMainDomain, + SolanaResolveAllDomainsTool, + SolanaCreateGibworkTask, + SolanaRockPaperScissorsTool, + SolanaTipLinkTool, + SolanaListNFTForSaleTool, + SolanaCancelNFTListingTool, + SolanaCloseEmptyTokenAccounts, + SolanaFetchTokenReportSummaryTool, + SolanaFetchTokenDetailedReportTool, + Solana3LandCreateSingle, + Solana3LandCreateCollection, + SolanaPerpOpenTradeTool, + SolanaPerpCloseTradeTool, + SolanaFlashOpenTrade, + SolanaFlashCloseTrade, +} from "./index"; export function createSolanaTools(solanaKit: SolanaAgentKit) { return [ @@ -2747,13 +144,5 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaPerpCloseTradeTool(solanaKit), new SolanaFlashOpenTrade(solanaKit), new SolanaFlashCloseTrade(solanaKit), - new Solana3LandCreateSingle(solanaKit), - new SolanaCreate2by2Multisig(solanaKit), - new SolanaDepositTo2by2Multisig(solanaKit), - new SolanaTransferFrom2by2Multisig(solanaKit), - new SolanaCreateProposal2by2Multisig(solanaKit), - new SolanaApproveProposal2by2Multisig(solanaKit), - new SolanaRejectProposal2by2Multisig(solanaKit), - new SolanaExecuteProposal2by2Multisig(solanaKit), ]; } diff --git a/src/langchain/jupiter/fetch_price.ts b/src/langchain/jupiter/fetch_price.ts new file mode 100644 index 0000000..78df83b --- /dev/null +++ b/src/langchain/jupiter/fetch_price.ts @@ -0,0 +1,34 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +/** + * 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()); + return JSON.stringify({ + status: "success", + tokenId: input.trim(), + priceInUSDC: price, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..93b9b2a --- /dev/null +++ b/src/langchain/jupiter/index.ts @@ -0,0 +1,4 @@ +export * from "./fetch_price"; +export * from "./token_data"; +export * from "./trade"; +export * from "./stake"; diff --git a/src/langchain/jupiter/stake.ts b/src/langchain/jupiter/stake.ts new file mode 100644 index 0000000..38a9263 --- /dev/null +++ b/src/langchain/jupiter/stake.ts @@ -0,0 +1,35 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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); + + const tx = await this.solanaKit.stake(parsedInput.amount); + + return JSON.stringify({ + status: "success", + message: "Staked successfully", + transaction: tx, + amount: parsedInput.amount, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/jupiter/token_data.ts b/src/langchain/jupiter/token_data.ts new file mode 100644 index 0000000..d202656 --- /dev/null +++ b/src/langchain/jupiter/token_data.ts @@ -0,0 +1,33 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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({ + status: "success", + tokenData, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..f3f03cc --- /dev/null +++ b/src/langchain/jupiter/trade.ts @@ -0,0 +1,48 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const tx = await this.solanaKit.trade( + new PublicKey(parsedInput.outputMint), + parsedInput.inputAmount, + parsedInput.inputMint + ? new PublicKey(parsedInput.inputMint) + : new PublicKey("So11111111111111111111111111111111111111112"), + parsedInput.slippageBps, + ); + + return JSON.stringify({ + status: "success", + message: "Trade executed successfully", + transaction: tx, + inputAmount: parsedInput.inputAmount, + inputToken: parsedInput.inputMint || "SOL", + outputToken: parsedInput.outputMint, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/lightprotocol/compressed_airdrop.ts b/src/langchain/lightprotocol/compressed_airdrop.ts new file mode 100644 index 0000000..1cf5e8a --- /dev/null +++ b/src/langchain/lightprotocol/compressed_airdrop.ts @@ -0,0 +1,46 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaCompressedAirdropTool extends Tool { + name = "solana_compressed_airdrop"; + description = `Airdrop SPL tokens with ZK Compression (also called as airdropping tokens) + + Inputs (input is a JSON string): + mintAddress: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required) + amount: number, the amount of tokens to airdrop per recipient, e.g., 42 (required) + decimals: number, the decimals of the token, e.g., 6 (required) + recipients: string[], the recipient addresses, e.g., ["1nc1nerator11111111111111111111111111111111"] (required) + 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 parsedInput = JSON.parse(input); + + const txs = await this.solanaKit.sendCompressedAirdrop( + parsedInput.mintAddress, + parsedInput.amount, + parsedInput.decimals, + parsedInput.recipients, + parsedInput.priorityFeeInLamports || 30_000, + parsedInput.shouldLog || false, + ); + + return JSON.stringify({ + status: "success", + message: `Airdropped ${parsedInput.amount} tokens to ${parsedInput.recipients.length} recipients.`, + transactionHashes: txs, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/lightprotocol/index.ts b/src/langchain/lightprotocol/index.ts new file mode 100644 index 0000000..85b1b94 --- /dev/null +++ b/src/langchain/lightprotocol/index.ts @@ -0,0 +1 @@ +export * from "./compressed_airdrop"; diff --git a/src/langchain/lulo/index.ts b/src/langchain/lulo/index.ts new file mode 100644 index 0000000..f4ecf39 --- /dev/null +++ b/src/langchain/lulo/index.ts @@ -0,0 +1 @@ +export * from "./lend_asset"; diff --git a/src/langchain/lulo/lend_asset.ts b/src/langchain/lulo/lend_asset.ts new file mode 100644 index 0000000..d1e2655 --- /dev/null +++ b/src/langchain/lulo/lend_asset.ts @@ -0,0 +1,35 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 { + const amount = JSON.parse(input).amount || input; + + const tx = await this.solanaKit.lendAssets(amount); + + return JSON.stringify({ + status: "success", + message: "Asset lent successfully", + transaction: tx, + amount, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/manifest/batch_order.ts b/src/langchain/manifest/batch_order.ts new file mode 100644 index 0000000..36dedbf --- /dev/null +++ b/src/langchain/manifest/batch_order.ts @@ -0,0 +1,97 @@ +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 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 } + ] + } + + 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.`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + let ordersToPlace: OrderParams[] = []; + + if (!parsedInput.marketId) { + throw new Error("Market ID is required"); + } + + if (parsedInput.pattern) { + ordersToPlace = generateOrdersfromPattern(parsedInput.pattern); + } else if (Array.isArray(parsedInput.orders)) { + ordersToPlace = parsedInput.orders; + } else { + throw new Error("Either pattern or orders array is required"); + } + + if (ordersToPlace.length === 0) { + throw new Error("No orders generated or provided"); + } + + ordersToPlace.forEach((order: OrderParams, index: number) => { + if (!order.quantity || !order.side || !order.price) { + throw new Error( + `Invalid order at index ${index}: quantity, side, and price are required`, + ); + } + if (order.side !== "Buy" && order.side !== "Sell") { + throw new Error( + `Invalid side at index ${index}: must be "Buy" or "Sell"`, + ); + } + }); + + const tx = await this.solanaKit.batchOrder( + new PublicKey(parsedInput.marketId), + parsedInput.orders, + ); + + return JSON.stringify({ + status: "success", + message: "Batch order executed successfully", + transaction: tx, + marketId: parsedInput.marketId, + orders: parsedInput.orders, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..4b185a9 --- /dev/null +++ b/src/langchain/manifest/cancel_orders.ts @@ -0,0 +1,35 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const marketId = new PublicKey(input.trim()); + const tx = await this.solanaKit.cancelAllOrders(marketId); + + return JSON.stringify({ + status: "success", + message: "Cancel orders successfully", + transaction: tx, + marketId, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..6657556 --- /dev/null +++ b/src/langchain/manifest/index.ts @@ -0,0 +1,5 @@ +export * from "./manifest_market"; +export * from "./batch_order"; +export * from "./cancel_orders"; +export * from "./limit_order"; +export * from "./withdraw"; diff --git a/src/langchain/manifest/limit_order.ts b/src/langchain/manifest/limit_order.ts new file mode 100644 index 0000000..72f26e5 --- /dev/null +++ b/src/langchain/manifest/limit_order.ts @@ -0,0 +1,49 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const tx = await this.solanaKit.limitOrder( + new PublicKey(parsedInput.marketId), + parsedInput.quantity, + parsedInput.side, + parsedInput.price, + ); + + return JSON.stringify({ + status: "success", + message: "Trade executed successfully", + transaction: tx, + marketId: parsedInput.marketId, + quantity: parsedInput.quantity, + side: parsedInput.side, + price: parsedInput.price, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..d05bc70 --- /dev/null +++ b/src/langchain/manifest/manifest_market.ts @@ -0,0 +1,41 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + + const tx = await this.solanaKit.manifestCreateMarket( + new PublicKey(inputFormat.baseMint), + new PublicKey(inputFormat.quoteMint), + ); + + return JSON.stringify({ + status: "success", + message: "Create manifest market successfully", + transaction: tx[0], + marketId: tx[1], + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/manifest/withdraw.ts b/src/langchain/manifest/withdraw.ts new file mode 100644 index 0000000..31a172f --- /dev/null +++ b/src/langchain/manifest/withdraw.ts @@ -0,0 +1,35 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const marketId = new PublicKey(input.trim()); + const tx = await this.solanaKit.withdrawAll(marketId); + + return JSON.stringify({ + status: "success", + message: "Withdrew successfully", + transaction: tx, + marketId, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/metaplex/deploy_collection.ts b/src/langchain/metaplex/deploy_collection.ts new file mode 100644 index 0000000..08f6d62 --- /dev/null +++ b/src/langchain/metaplex/deploy_collection.ts @@ -0,0 +1,37 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const result = await this.solanaKit.deployCollection(parsedInput); + + return JSON.stringify({ + status: "success", + message: "Collection deployed successfully", + collectionAddress: result.collectionAddress.toString(), + name: parsedInput.name, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..77eb692 --- /dev/null +++ b/src/langchain/metaplex/deploy_token.ts @@ -0,0 +1,45 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaDeployTokenTool extends Tool { + name = "solana_deploy_token"; + description = `Deploy a new token on Solana blockchain. + + Inputs (input is a JSON string): + name: string, eg "My Token" (required) + uri: string, eg "https://example.com/token.json" (required) + symbol: string, eg "MTK" (required) + 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 parsedInput = JSON.parse(input); + + const result = await this.solanaKit.deployToken( + parsedInput.name, + parsedInput.uri, + parsedInput.symbol, + parsedInput.decimals, + parsedInput.initialSupply, + ); + + return JSON.stringify({ + status: "success", + message: "Token deployed successfully", + mintAddress: result.mint.toString(), + decimals: parsedInput.decimals || 9, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..7cdfe15 --- /dev/null +++ b/src/langchain/metaplex/index.ts @@ -0,0 +1,3 @@ +export * from "./deploy_collection"; +export * from "./mint_nft"; +export * from "./deploy_token"; diff --git a/src/langchain/metaplex/mint_nft.ts b/src/langchain/metaplex/mint_nft.ts new file mode 100644 index 0000000..775c6a4 --- /dev/null +++ b/src/langchain/metaplex/mint_nft.ts @@ -0,0 +1,53 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaMintNFTTool extends Tool { + name = "solana_mint_nft"; + description = `Mint a new NFT in a collection on Solana blockchain. + + Inputs (input is a JSON string): + 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 which is ${this.solanaKit.wallet_address.toString()}`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const result = await this.solanaKit.mintNFT( + new PublicKey(parsedInput.collectionMint), + { + name: parsedInput.name, + uri: parsedInput.uri, + }, + parsedInput.recipient + ? new PublicKey(parsedInput.recipient) + : this.solanaKit.wallet_address, + ); + + return JSON.stringify({ + status: "success", + message: "NFT minted successfully", + mintAddress: result.mint.toString(), + metadata: { + name: parsedInput.name, + symbol: parsedInput.symbol, + uri: parsedInput.uri, + }, + recipient: parsedInput.recipient || result.mint.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/openbook/index.ts b/src/langchain/openbook/index.ts new file mode 100644 index 0000000..22b2ef1 --- /dev/null +++ b/src/langchain/openbook/index.ts @@ -0,0 +1 @@ +export * from "./openbook_market"; diff --git a/src/langchain/openbook/openbook_market.ts b/src/langchain/openbook/openbook_market.ts new file mode 100644 index 0000000..4f6b63c --- /dev/null +++ b/src/langchain/openbook/openbook_market.ts @@ -0,0 +1,45 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaOpenbookCreateMarket extends Tool { + name = "solana_openbook_create_market"; + description = `Openbook marketId, required for ammv4 + + Inputs (input is a json string): + baseMint: string (required) + quoteMint: string (required) + lotSize: number (required) + tickSize: number (required) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + + const tx = await this.solanaKit.openbookCreateMarket( + new PublicKey(inputFormat.baseMint), + new PublicKey(inputFormat.quoteMint), + + inputFormat.lotSize, + inputFormat.tickSize, + ); + + return JSON.stringify({ + status: "success", + message: "Openbook market created successfully", + transaction: tx, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/orca/index.ts b/src/langchain/orca/index.ts new file mode 100644 index 0000000..10358af --- /dev/null +++ b/src/langchain/orca/index.ts @@ -0,0 +1,6 @@ +export * from "./orca_clmm"; +export * from "./orca_single_sided_pool"; +export * from "./orca_position"; +export * from "./orca_fetch_positions"; +export * from "./orca_centered_position"; +export * from "./orca_single_sided_position"; diff --git a/src/langchain/orca/orca_centered_position.ts b/src/langchain/orca/orca_centered_position.ts new file mode 100644 index 0000000..ca7abca --- /dev/null +++ b/src/langchain/orca/orca_centered_position.ts @@ -0,0 +1,54 @@ +import { PublicKey } from "@solana/web3.js"; +import { Decimal } from "decimal.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + Inputs (JSON string): + - whirlpoolAddress: string, address of the Orca Whirlpool (required). + - priceOffsetBps: number, bps offset (one side) from the current pool price, e.g., 500 for 5% (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 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( + whirlpoolAddress, + priceOffsetBps, + inputTokenMint, + inputAmount, + ); + + return JSON.stringify({ + status: "success", + message: "Centered liquidity position opened successfully.", + transaction: txId, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..8508a45 --- /dev/null +++ b/src/langchain/orca/orca_clmm.ts @@ -0,0 +1,58 @@ +import { PublicKey } from "@solana/web3.js"; +import { Decimal } from "decimal.js"; +import { FEE_TIERS } from "../../tools/orca"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + Inputs (JSON string): + - mintDeploy: string, the mint of the token you want to deploy (required). + - mintPair: string, The mint of the token you want to pair the deployed mint with (required). + - 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 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( + `Invalid feeTier. Available options: ${Object.keys(FEE_TIERS).join( + ", ", + )}`, + ); + } + + const txId = await this.solanaKit.orcaCreateCLMM( + mintA, + mintB, + initialPrice, + feeTier, + ); + + return JSON.stringify({ + status: "success", + message: + "CLMM pool created successfully. Note: No liquidity was added.", + transaction: txId, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..820780b --- /dev/null +++ b/src/langchain/orca/orca_fetch_positions.ts @@ -0,0 +1,29 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 positiont mint addresses as keys and position status details as values.`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(): Promise { + try { + const txId = await this.solanaKit.orcaFetchPositions(); + + return JSON.stringify({ + status: "success", + message: "Liquidity positions fetched.", + transaction: txId, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..a72ecc2 --- /dev/null +++ b/src/langchain/orca/orca_position.ts @@ -0,0 +1,39 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaClosePosition extends Tool { + name = "orca_close_position"; + description = `Closes an existing liquidity position in an Orca Whirlpool. This function fetches the position + details using the provided mint address and closes the position with a 1% slippage. + + Inputs (JSON string): + - positionMintAddress: string, the address of the position mint that represents the liquidity position.`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + 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, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..549373b --- /dev/null +++ b/src/langchain/orca/orca_single_sided_pool.ts @@ -0,0 +1,65 @@ +import { PublicKey } from "@solana/web3.js"; +import { Decimal } from "decimal.js"; +import { FEE_TIERS } from "../../tools/orca"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + This function initializes a single-sided liquidity pool, ideal for community driven project, fair launches, and fundraising. Minimize price impact by setting a narrow price range. + + Inputs (JSON string): + - depositTokenAmount: number, in units of the deposit token including decimals, e.g., 1000000000 (required). + - depositTokenMint: string, mint address of the deposit token, e.g., "DepositTokenMintAddress" (required). + - otherTokenMint: string, mint address of the other token, e.g., "OtherTokenMintAddress" (required). + - initialPrice: number, initial price of the deposit token in terms of the other token, e.g., 0.001 (required). + - 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 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( + `Invalid feeTier. Available options: ${Object.keys(FEE_TIERS).join( + ", ", + )}`, + ); + } + + const txId = await this.solanaKit.orcaCreateSingleSidedLiquidityPool( + depositTokenAmount, + depositTokenMint, + otherTokenMint, + initialPrice, + maxPrice, + feeTier, + ); + + return JSON.stringify({ + status: "success", + message: "Single-sided Whirlpool created successfully", + transaction: txId, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..d7b993e --- /dev/null +++ b/src/langchain/orca/orca_single_sided_position.ts @@ -0,0 +1,58 @@ +import { PublicKey } from "@solana/web3.js"; +import { Decimal } from "decimal.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 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 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( + whirlpoolAddress, + distanceFromCurrentPriceBps, + widthBps, + inputTokenMint, + inputAmount, + ); + + return JSON.stringify({ + status: "success", + message: "Single-sided liquidity position opened successfully.", + transaction: txId, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/pumpfun/index.ts b/src/langchain/pumpfun/index.ts new file mode 100644 index 0000000..2d7cc24 --- /dev/null +++ b/src/langchain/pumpfun/index.ts @@ -0,0 +1 @@ +export * from "./launch_pumpfun_token"; diff --git a/src/langchain/pumpfun/launch_pumpfun_token.ts b/src/langchain/pumpfun/launch_pumpfun_token.ts new file mode 100644 index 0000000..6fbabcf --- /dev/null +++ b/src/langchain/pumpfun/launch_pumpfun_token.ts @@ -0,0 +1,79 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaPumpfunTokenLaunchTool extends Tool { + name = "solana_launch_pumpfun_token"; + + description = `This tool can be used to launch a token on Pump.fun, + do not use this tool for any other purpose, or for creating SPL tokens. + If the user asks you to chose the parameters, you should generate valid values. + For generating the image, you can use the solana_create_image tool. + + Inputs: + tokenName: string, eg "PumpFun Token", + tokenTicker: string, eg "PUMP", + 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"); + } + if (!input.tokenTicker || typeof input.tokenTicker !== "string") { + throw new Error("tokenTicker is required and must be a string"); + } + if (!input.description || typeof input.description !== "string") { + throw new Error("description is required and must be a string"); + } + if (!input.imageUrl || typeof input.imageUrl !== "string") { + throw new Error("imageUrl is required and must be a string"); + } + if ( + input.initialLiquiditySOL !== undefined && + typeof input.initialLiquiditySOL !== "number" + ) { + throw new Error("initialLiquiditySOL must be a number when provided"); + } + } + + protected async _call(input: string): Promise { + try { + // Parse and normalize input + input = input.trim(); + const parsedInput = JSON.parse(input); + + this.validateInput(parsedInput); + + // Launch token with validated input + await this.solanaKit.launchPumpFunToken( + parsedInput.tokenName, + parsedInput.tokenTicker, + parsedInput.description, + parsedInput.imageUrl, + { + twitter: parsedInput.twitter, + telegram: parsedInput.telegram, + website: parsedInput.website, + initialLiquiditySOL: parsedInput.initialLiquiditySOL, + }, + ); + + return JSON.stringify({ + status: "success", + message: "Token launched successfully on Pump.fun", + tokenName: parsedInput.tokenName, + tokenTicker: parsedInput.tokenTicker, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/pyth/index.ts b/src/langchain/pyth/index.ts new file mode 100644 index 0000000..5cf3952 --- /dev/null +++ b/src/langchain/pyth/index.ts @@ -0,0 +1 @@ +export * from "./pyth_price"; diff --git a/src/langchain/pyth/pyth_price.ts b/src/langchain/pyth/pyth_price.ts new file mode 100644 index 0000000..0ac524c --- /dev/null +++ b/src/langchain/pyth/pyth_price.ts @@ -0,0 +1,39 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PythFetchPriceResponse } from "../../index"; + +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: PythFetchPriceResponse = { + status: "success", + tokenSymbol: input, + priceFeedID, + price, + }; + + return JSON.stringify(response); + } catch (error: any) { + const response: PythFetchPriceResponse = { + status: "error", + tokenSymbol: input, + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }; + return JSON.stringify(response); + } + } +} diff --git a/src/langchain/raydium/index.ts b/src/langchain/raydium/index.ts new file mode 100644 index 0000000..7d29f7a --- /dev/null +++ b/src/langchain/raydium/index.ts @@ -0,0 +1,4 @@ +export * from "./raydium_amm"; +export * from "./raydium_clmm"; +export * from "./raydium_cpmm"; +export * from "./types"; diff --git a/src/langchain/raydium/raydium_amm.ts b/src/langchain/raydium/raydium_amm.ts new file mode 100644 index 0000000..f31858a --- /dev/null +++ b/src/langchain/raydium/raydium_amm.ts @@ -0,0 +1,45 @@ +import { PublicKey } from "@solana/web3.js"; +import { BN } from "@coral-xyz/anchor"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaRaydiumCreateAmmV4 extends Tool { + name = "raydium_create_ammV4"; + description = `Raydium's Legacy AMM that requires an OpenBook marketID + + Inputs (input is a json string): + marketId: string (required) + baseAmount: number(int), eg: 111111 (required) + quoteAmount: number(int), eg: 111111 (required) + startTime: number(seconds), eg: now number or zero (required) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + + const tx = await this.solanaKit.raydiumCreateAmmV4( + new PublicKey(inputFormat.marketId), + new BN(inputFormat.baseAmount), + new BN(inputFormat.quoteAmount), + new BN(inputFormat.startTime), + ); + + return JSON.stringify({ + status: "success", + message: "Raydium amm v4 pool created successfully", + transaction: tx, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..9d493e5 --- /dev/null +++ b/src/langchain/raydium/raydium_clmm.ts @@ -0,0 +1,50 @@ +import { PublicKey } from "@solana/web3.js"; +import { BN } from "@coral-xyz/anchor"; +import { Decimal } from "decimal.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaRaydiumCreateClmm extends Tool { + name = "raydium_create_clmm"; + description = `Concentrated liquidity market maker, custom liquidity ranges, increased capital efficiency + + Inputs (input is a json string): + mint1: string (required) + 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) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + + const tx = await this.solanaKit.raydiumCreateClmm( + new PublicKey(inputFormat.mint1), + new PublicKey(inputFormat.mint2), + + new PublicKey(inputFormat.configId), + + new Decimal(inputFormat.initialPrice), + new BN(inputFormat.startTime), + ); + + return JSON.stringify({ + status: "success", + message: "Raydium clmm pool created successfully", + transaction: tx, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..81ded50 --- /dev/null +++ b/src/langchain/raydium/raydium_cpmm.ts @@ -0,0 +1,52 @@ +import { PublicKey } from "@solana/web3.js"; +import { BN } from "@coral-xyz/anchor"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaRaydiumCreateCpmm extends Tool { + name = "raydium_create_cpmm"; + description = `Raydium's newest CPMM, does not require marketID, supports Token 2022 standard + + Inputs (input is a json string): + mint1: string (required) + mint2: string (required) + 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) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + + const tx = await this.solanaKit.raydiumCreateCpmm( + 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({ + status: "success", + message: "Raydium cpmm pool created successfully", + transaction: tx, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/raydium/types.ts b/src/langchain/raydium/types.ts new file mode 100644 index 0000000..8eeab17 --- /dev/null +++ b/src/langchain/raydium/types.ts @@ -0,0 +1,23 @@ +export interface RaydiumAmmV4Input { + marketId: string; + baseAmount: number | string; + quoteAmount: number | string; + startTime: number; +} + +export interface RaydiumClmmInput { + mint1: string; + mint2: string; + configId: string; + initialPrice: number | string; + startTime: number; +} + +export interface RaydiumCpmmInput { + mint1: string; + mint2: string; + configId: string; + mintAAmount: number | string; + mintBAmount: number | string; + startTime: number; +} diff --git a/src/langchain/rugcheck/index.ts b/src/langchain/rugcheck/index.ts new file mode 100644 index 0000000..a058c2d --- /dev/null +++ b/src/langchain/rugcheck/index.ts @@ -0,0 +1,2 @@ +export * from "./token_report_summary"; +export * from "./token_report_detailed"; diff --git a/src/langchain/rugcheck/token_report_detailed.ts b/src/langchain/rugcheck/token_report_detailed.ts new file mode 100644 index 0000000..9d45bac --- /dev/null +++ b/src/langchain/rugcheck/token_report_detailed.ts @@ -0,0 +1,33 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaFetchTokenDetailedReportTool extends Tool { + name = "solana_fetch_token_detailed_report"; + description = `Fetches a detailed report for a specific token from RugCheck. + Inputs: + - mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const mint = input.trim(); + const detailedReport = + await this.solanaKit.fetchTokenDetailedReport(mint); + + return JSON.stringify({ + status: "success", + message: "Detailed token report fetched successfully", + report: detailedReport, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TOKEN_DETAILED_REPORT_ERROR", + }); + } + } +} diff --git a/src/langchain/rugcheck/token_report_summary.ts b/src/langchain/rugcheck/token_report_summary.ts new file mode 100644 index 0000000..766abdb --- /dev/null +++ b/src/langchain/rugcheck/token_report_summary.ts @@ -0,0 +1,32 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaFetchTokenReportSummaryTool extends Tool { + name = "solana_fetch_token_report_summary"; + description = `Fetches a summary report for a specific token from RugCheck. + Inputs: + - mint: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required).`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const mint = input.trim(); + const report = await this.solanaKit.fetchTokenReportSummary(mint); + + return JSON.stringify({ + status: "success", + message: "Token report summary fetched successfully", + report, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_TOKEN_REPORT_SUMMARY_ERROR", + }); + } + } +} diff --git a/src/langchain/sendarcade/index.ts b/src/langchain/sendarcade/index.ts new file mode 100644 index 0000000..9d6a8d7 --- /dev/null +++ b/src/langchain/sendarcade/index.ts @@ -0,0 +1 @@ +export * from "./rock_paper_scissors"; diff --git a/src/langchain/sendarcade/rock_paper_scissors.ts b/src/langchain/sendarcade/rock_paper_scissors.ts new file mode 100644 index 0000000..ab90107 --- /dev/null +++ b/src/langchain/sendarcade/rock_paper_scissors.ts @@ -0,0 +1,52 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaRockPaperScissorsTool extends Tool { + name = "rock_paper_scissors"; + description = `Play rock paper scissors to win SEND coins. + + Inputs (input is a JSON string): + 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 parsedInput = JSON.parse(input); + this.validateInput(parsedInput); + const result = await this.solanaKit.rockPaperScissors( + Number(parsedInput['"amount"']), + parsedInput['"choice"'].replace(/^"|"$/g, "") as + | "rock" + | "paper" + | "scissors", + ); + + return JSON.stringify({ + status: "success", + message: result, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/sns/get_domain.ts b/src/langchain/sns/get_domain.ts new file mode 100644 index 0000000..6456879 --- /dev/null +++ b/src/langchain/sns/get_domain.ts @@ -0,0 +1,35 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const account = new PublicKey(input.trim()); + const domain = await this.solanaKit.getPrimaryDomain(account); + + return JSON.stringify({ + status: "success", + message: "Primary domain retrieved successfully", + domain, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/sns/index.ts b/src/langchain/sns/index.ts new file mode 100644 index 0000000..a7976f0 --- /dev/null +++ b/src/langchain/sns/index.ts @@ -0,0 +1,4 @@ +export * from "./register_domain"; +export * from "./resolve_domain"; +export * from "./get_domain"; +export * from "./main_domain"; diff --git a/src/langchain/sns/main_domain.ts b/src/langchain/sns/main_domain.ts new file mode 100644 index 0000000..4bd17e8 --- /dev/null +++ b/src/langchain/sns/main_domain.ts @@ -0,0 +1,35 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const ownerPubkey = new PublicKey(input.trim()); + const mainDomain = + await this.solanaKit.getMainAllDomainsDomain(ownerPubkey); + + return JSON.stringify({ + status: "success", + message: "Main domain fetched successfully", + domain: mainDomain, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "FETCH_MAIN_DOMAIN_ERROR", + }); + } + } +} diff --git a/src/langchain/sns/register_domain.ts b/src/langchain/sns/register_domain.ts new file mode 100644 index 0000000..d59d668 --- /dev/null +++ b/src/langchain/sns/register_domain.ts @@ -0,0 +1,54 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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) + `; + + 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 parsedInput = JSON.parse(input); + this.validateInput(parsedInput); + + const tx = await this.solanaKit.registerDomain( + parsedInput.name, + parsedInput.spaceKB || 1, + ); + + return JSON.stringify({ + status: "success", + message: "Domain registered successfully", + transaction: tx, + domain: `${parsedInput.name}.sol`, + spaceKB: parsedInput.spaceKB || 1, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/sns/resolve_domain.ts b/src/langchain/sns/resolve_domain.ts new file mode 100644 index 0000000..77e71a6 --- /dev/null +++ b/src/langchain/sns/resolve_domain.ts @@ -0,0 +1,36 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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) + `; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const domain = input.trim(); + const publicKey = await this.solanaKit.resolveSolDomain(domain); + + return JSON.stringify({ + status: "success", + message: "Domain resolved successfully", + publicKey: publicKey.toBase58(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/solana/balance.ts b/src/langchain/solana/balance.ts new file mode 100644 index 0000000..fd84b88 --- /dev/null +++ b/src/langchain/solana/balance.ts @@ -0,0 +1,37 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaBalanceTool extends Tool { + name = "solana_balance"; + description = `Get the balance of a Solana wallet or token account. + + If you want to get the balance of your wallet, you don't need to provide the tokenAddress. + If no tokenAddress is provided, the balance will be in SOL. + + Inputs ( input is a JSON string ): + tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const tokenAddress = input ? new PublicKey(input) : undefined; + const balance = await this.solanaKit.getBalance(tokenAddress); + + return JSON.stringify({ + status: "success", + balance, + token: input || "SOL", + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..c29f7f1 --- /dev/null +++ b/src/langchain/solana/balance_other.ts @@ -0,0 +1,46 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + If no tokenAddress is provided, the SOL balance of the wallet will be returned. + + Inputs ( input is a JSON string ): + walletAddress: string, eg "GDEkQF7UMr7RLv1KQKMtm8E2w3iafxJLtyXu3HVQZnME" (required) + tokenAddress: string, eg "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const { walletAddress, tokenAddress } = JSON.parse(input); + + const tokenPubKey = tokenAddress + ? new PublicKey(tokenAddress) + : undefined; + + const balance = await this.solanaKit.getBalanceOther( + new PublicKey(walletAddress), + tokenPubKey, + ); + + return JSON.stringify({ + status: "success", + balance, + wallet: walletAddress, + token: tokenAddress || "SOL", + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..9a1bba9 --- /dev/null +++ b/src/langchain/solana/close_empty_accounts.ts @@ -0,0 +1,30 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 } = + await this.solanaKit.closeEmptyTokenAccounts(); + + return JSON.stringify({ + 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, + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..4f052d8 --- /dev/null +++ b/src/langchain/solana/get_tps.ts @@ -0,0 +1,20 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 `Solana (mainnet-beta) current transactions per second: ${tps}`; + } catch (error: any) { + return `Error fetching TPS: ${error.message}`; + } + } +} diff --git a/src/langchain/solana/index.ts b/src/langchain/solana/index.ts new file mode 100644 index 0000000..02db35c --- /dev/null +++ b/src/langchain/solana/index.ts @@ -0,0 +1,6 @@ +export * from "./get_tps"; +export * from "./request_funds"; +export * from "./balance"; +export * from "./balance_other"; +export * from "./close_empty_accounts"; +export * from "./transfer"; diff --git a/src/langchain/solana/request_funds.ts b/src/langchain/solana/request_funds.ts new file mode 100644 index 0000000..832db99 --- /dev/null +++ b/src/langchain/solana/request_funds.ts @@ -0,0 +1,29 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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(); + + return JSON.stringify({ + status: "success", + message: "Successfully requested faucet funds", + network: this.solanaKit.connection.rpcEndpoint.split("/")[2], + }); + } catch (error: any) { + 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 new file mode 100644 index 0000000..2f21ebf --- /dev/null +++ b/src/langchain/solana/transfer.ts @@ -0,0 +1,49 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaTransferTool extends Tool { + name = "solana_transfer"; + description = `Transfer tokens or SOL to another address ( also called as wallet address ). + + Inputs ( input is a JSON string ): + to: string, eg "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk" (required) + 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 parsedInput = JSON.parse(input); + + const recipient = new PublicKey(parsedInput.to); + const mintAddress = parsedInput.mint + ? new PublicKey(parsedInput.mint) + : undefined; + + const tx = await this.solanaKit.transfer( + recipient, + parsedInput.amount, + mintAddress, + ); + + return JSON.stringify({ + status: "success", + message: "Transfer completed successfully", + amount: parsedInput.amount, + recipient: parsedInput.to, + token: parsedInput.mint || "SOL", + transaction: tx, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/solayer/index.ts b/src/langchain/solayer/index.ts new file mode 100644 index 0000000..a40a029 --- /dev/null +++ b/src/langchain/solayer/index.ts @@ -0,0 +1 @@ +export * from "./restake"; diff --git a/src/langchain/solayer/restake.ts b/src/langchain/solayer/restake.ts new file mode 100644 index 0000000..d13291f --- /dev/null +++ b/src/langchain/solayer/restake.ts @@ -0,0 +1,35 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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); + + const tx = await this.solanaKit.restake(parsedInput.amount); + + return JSON.stringify({ + status: "success", + message: "Staked successfully", + transaction: tx, + amount: parsedInput.amount, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/approve_proposal.ts b/src/langchain/squads_multisig/approve_proposal.ts new file mode 100644 index 0000000..23bac26 --- /dev/null +++ b/src/langchain/squads_multisig/approve_proposal.ts @@ -0,0 +1,38 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + If proposalIndex is not provided, the latest index will automatically be fetched and used. + + 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); + const proposalIndex = inputFormat.proposalIndex ?? undefined; + + const tx = await this.solanaKit.approveMultisigProposal(proposalIndex); + + return JSON.stringify({ + status: "success", + message: "Proposal approved successfully", + transaction: tx, + proposalIndex: proposalIndex.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "APPROVE_PROPOSAL_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/create_multisig.ts b/src/langchain/squads_multisig/create_multisig.ts new file mode 100644 index 0000000..4628d25 --- /dev/null +++ b/src/langchain/squads_multisig/create_multisig.ts @@ -0,0 +1,38 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; + +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. + + Note: For one AI agent, only one 2-by-2 multisig can be created as it is pair-wise. + + 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); + const creator = new PublicKey(inputFormat.creator); + + const multisig = await this.solanaKit.createSquadsMultisig(creator); + + return JSON.stringify({ + status: "success", + message: "2-by-2 multisig account created successfully", + multisig, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "CREATE_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/create_proposal.ts b/src/langchain/squads_multisig/create_proposal.ts new file mode 100644 index 0000000..fb79cde --- /dev/null +++ b/src/langchain/squads_multisig/create_proposal.ts @@ -0,0 +1,38 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + If transactionIndex is not provided, the latest index will automatically be fetched and used. + + 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); + const transactionIndex = inputFormat.transactionIndex ?? undefined; + + const tx = await this.solanaKit.createMultisigProposal(transactionIndex); + + return JSON.stringify({ + status: "success", + message: "Proposal created successfully", + transaction: tx, + transactionIndex: transactionIndex?.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "CREATE_PROPOSAL_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/deposit_to_multisig.ts b/src/langchain/squads_multisig/deposit_to_multisig.ts new file mode 100644 index 0000000..4e9645c --- /dev/null +++ b/src/langchain/squads_multisig/deposit_to_multisig.ts @@ -0,0 +1,37 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import Decimal from "decimal.js"; + +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); + const amount = new Decimal(inputFormat.amount); + + const tx = await this.solanaKit.depositToMultisig(amount.toNumber()); + + return JSON.stringify({ + status: "success", + message: "Funds deposited to 2-by-2 multisig account successfully", + transaction: tx, + amount: amount.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "DEPOSIT_TO_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/execute_proposal.ts b/src/langchain/squads_multisig/execute_proposal.ts new file mode 100644 index 0000000..4c6463b --- /dev/null +++ b/src/langchain/squads_multisig/execute_proposal.ts @@ -0,0 +1,38 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + If proposalIndex is not provided, the latest index will automatically be fetched and used. + + 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); + const proposalIndex = inputFormat.proposalIndex ?? undefined; + + const tx = await this.solanaKit.executeMultisigTransaction(proposalIndex); + + return JSON.stringify({ + status: "success", + message: "Proposal executed successfully", + transaction: tx, + proposalIndex: proposalIndex.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "EXECUTE_PROPOSAL_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/index.ts b/src/langchain/squads_multisig/index.ts new file mode 100644 index 0000000..5ceac36 --- /dev/null +++ b/src/langchain/squads_multisig/index.ts @@ -0,0 +1,7 @@ +export * from "./approve_proposal"; +export * from "./create_multisig"; +export * from "./create_proposal"; +export * from "./deposit_to_multisig"; +export * from "./execute_proposal"; +export * from "./reject_proposal"; +export * from "./transfer_from_multisig"; diff --git a/src/langchain/squads_multisig/reject_proposal.ts b/src/langchain/squads_multisig/reject_proposal.ts new file mode 100644 index 0000000..30a62fc --- /dev/null +++ b/src/langchain/squads_multisig/reject_proposal.ts @@ -0,0 +1,38 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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. + + If proposalIndex is not provided, the latest index will automatically be fetched and used. + + 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); + const proposalIndex = inputFormat.proposalIndex ?? undefined; + + const tx = await this.solanaKit.rejectMultisigProposal(proposalIndex); + + return JSON.stringify({ + status: "success", + message: "Proposal rejected successfully", + transaction: tx, + proposalIndex: proposalIndex.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "REJECT_PROPOSAL_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/squads_multisig/transfer_from_multisig.ts b/src/langchain/squads_multisig/transfer_from_multisig.ts new file mode 100644 index 0000000..ef657ff --- /dev/null +++ b/src/langchain/squads_multisig/transfer_from_multisig.ts @@ -0,0 +1,44 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; +import Decimal from "decimal.js"; + +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. + + Inputs (JSON string): + - 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); + const amount = new Decimal(inputFormat.amount); + const recipient = new PublicKey(inputFormat.recipient); + + const tx = await this.solanaKit.transferFromMultisig( + amount.toNumber(), + recipient, + ); + + return JSON.stringify({ + status: "success", + message: "Transaction added to 2-by-2 multisig account successfully", + transaction: tx, + amount: amount.toString(), + recipient: recipient.toString(), + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "TRANSFER_FROM_2BY2_MULTISIG_ERROR", + }); + } + } +} diff --git a/src/langchain/tensor/cancel_listing.ts b/src/langchain/tensor/cancel_listing.ts new file mode 100644 index 0000000..8fd764d --- /dev/null +++ b/src/langchain/tensor/cancel_listing.ts @@ -0,0 +1,38 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 parsedInput = JSON.parse(input); + + const tx = await this.solanaKit.tensorCancelListing( + new PublicKey(parsedInput.nftMint), + ); + + return JSON.stringify({ + status: "success", + message: "NFT listing cancelled successfully", + transaction: tx, + nftMint: parsedInput.nftMint, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/tensor/index.ts b/src/langchain/tensor/index.ts new file mode 100644 index 0000000..d7641b7 --- /dev/null +++ b/src/langchain/tensor/index.ts @@ -0,0 +1,2 @@ +export * from "./list_nft"; +export * from "./cancel_listing"; diff --git a/src/langchain/tensor/list_nft.ts b/src/langchain/tensor/list_nft.ts new file mode 100644 index 0000000..a54ea2b --- /dev/null +++ b/src/langchain/tensor/list_nft.ts @@ -0,0 +1,57 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaListNFTForSaleTool extends Tool { + name = "solana_list_nft_for_sale"; + description = `List an NFT for sale on Tensor Trade. + + Inputs (input is a JSON string): + 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 parsedInput = JSON.parse(input); + + // Validate NFT ownership first + const nftAccount = + await this.solanaKit.connection.getTokenAccountsByOwner( + this.solanaKit.wallet_address, + { mint: new PublicKey(parsedInput.nftMint) }, + ); + + if (nftAccount.value.length === 0) { + return JSON.stringify({ + status: "error", + message: + "NFT not found in wallet. Please make sure you own this NFT.", + code: "NFT_NOT_FOUND", + }); + } + + const tx = await this.solanaKit.tensorListNFT( + new PublicKey(parsedInput.nftMint), + parsedInput.price, + ); + + return JSON.stringify({ + status: "success", + message: "NFT listed for sale successfully", + transaction: tx, + price: parsedInput.price, + nftMint: parsedInput.nftMint, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/tiplink/index.ts b/src/langchain/tiplink/index.ts new file mode 100644 index 0000000..b480c71 --- /dev/null +++ b/src/langchain/tiplink/index.ts @@ -0,0 +1 @@ +export * from "./tiplink"; diff --git a/src/langchain/tiplink/tiplink.ts b/src/langchain/tiplink/tiplink.ts new file mode 100644 index 0000000..f029b3b --- /dev/null +++ b/src/langchain/tiplink/tiplink.ts @@ -0,0 +1,50 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +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 parsedInput = JSON.parse(input); + + if (!parsedInput.amount) { + throw new Error("Amount is required"); + } + + const amount = parseFloat(parsedInput.amount); + const splmintAddress = parsedInput.splmintAddress + ? new PublicKey(parsedInput.splmintAddress) + : undefined; + + const { url, signature } = await this.solanaKit.createTiplink( + amount, + splmintAddress, + ); + + return JSON.stringify({ + status: "success", + url, + signature, + amount, + tokenType: splmintAddress ? "SPL" : "SOL", + message: `TipLink created successfully`, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/tools/create_3land_collectible.ts b/src/tools/3land/create_3land_collectible.ts similarity index 100% rename from src/tools/create_3land_collectible.ts rename to src/tools/3land/create_3land_collectible.ts diff --git a/src/tools/3land/index.ts b/src/tools/3land/index.ts new file mode 100644 index 0000000..13200de --- /dev/null +++ b/src/tools/3land/index.ts @@ -0,0 +1 @@ +export * from "./create_3land_collectible"; diff --git a/src/tools/adrena_perp_trading.ts b/src/tools/adrena/adrena_perp_trading.ts similarity index 98% rename from src/tools/adrena_perp_trading.ts rename to src/tools/adrena/adrena_perp_trading.ts index 8c47216..ec6e8f1 100644 --- a/src/tools/adrena_perp_trading.ts +++ b/src/tools/adrena/adrena_perp_trading.ts @@ -3,13 +3,13 @@ import { SystemProgram, TransactionInstruction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; -import { TOKENS, DEFAULT_OPTIONS } from "../constants"; +import { SolanaAgentKit } from "../../index"; +import { TOKENS, DEFAULT_OPTIONS } from "../../constants"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { BN } from "@coral-xyz/anchor"; -import AdrenaClient from "../utils/AdrenaClient"; -import { sendTx } from "../utils/send_tx"; +import AdrenaClient from "../../utils/AdrenaClient"; +import { sendTx } from "../../utils/send_tx"; const PRICE_DECIMALS = 10; const ADRENA_PROGRAM_ID = new PublicKey( diff --git a/src/tools/adrena/index.ts b/src/tools/adrena/index.ts new file mode 100644 index 0000000..8ad923a --- /dev/null +++ b/src/tools/adrena/index.ts @@ -0,0 +1 @@ +export * from "./adrena_perp_trading"; diff --git a/src/tools/create_image.ts b/src/tools/agent/create_image.ts similarity index 95% rename from src/tools/create_image.ts rename to src/tools/agent/create_image.ts index 106f3c2..91d5913 100644 --- a/src/tools/create_image.ts +++ b/src/tools/agent/create_image.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import OpenAI from "openai"; /** diff --git a/src/tools/get_wallet_address.ts b/src/tools/agent/get_wallet_address.ts similarity index 81% rename from src/tools/get_wallet_address.ts rename to src/tools/agent/get_wallet_address.ts index bf3c763..c302a86 100644 --- a/src/tools/get_wallet_address.ts +++ b/src/tools/agent/get_wallet_address.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; /** * Get the agents wallet address diff --git a/src/tools/agent/index.ts b/src/tools/agent/index.ts new file mode 100644 index 0000000..b3f2f51 --- /dev/null +++ b/src/tools/agent/index.ts @@ -0,0 +1,2 @@ +export * from "./create_image"; +export * from "./get_wallet_address"; diff --git a/src/tools/get_all_domains_tlds.ts b/src/tools/alldomains/get_all_domains_tlds.ts similarity index 91% rename from src/tools/get_all_domains_tlds.ts rename to src/tools/alldomains/get_all_domains_tlds.ts index 4d2fcbd..2b84c2a 100644 --- a/src/tools/get_all_domains_tlds.ts +++ b/src/tools/alldomains/get_all_domains_tlds.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { getAllTld } from "@onsol/tldparser"; /** diff --git a/src/tools/get_owned_all_domains.ts b/src/tools/alldomains/get_owned_all_domains.ts similarity index 94% rename from src/tools/get_owned_all_domains.ts rename to src/tools/alldomains/get_owned_all_domains.ts index aa52e1e..87fda7c 100644 --- a/src/tools/get_owned_all_domains.ts +++ b/src/tools/alldomains/get_owned_all_domains.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; import { PublicKey } from "@solana/web3.js"; import { TldParser } from "@onsol/tldparser"; diff --git a/src/tools/get_owned_domains_for_tld.ts b/src/tools/alldomains/get_owned_domains_for_tld.ts similarity index 94% rename from src/tools/get_owned_domains_for_tld.ts rename to src/tools/alldomains/get_owned_domains_for_tld.ts index c3fde6a..347a180 100644 --- a/src/tools/get_owned_domains_for_tld.ts +++ b/src/tools/alldomains/get_owned_domains_for_tld.ts @@ -1,5 +1,5 @@ import { TldParser } from "@onsol/tldparser"; -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; /** * Get all domains owned by an address for a specific TLD * @param agent SolanaAgentKit instance diff --git a/src/tools/alldomains/index.ts b/src/tools/alldomains/index.ts new file mode 100644 index 0000000..1204edb --- /dev/null +++ b/src/tools/alldomains/index.ts @@ -0,0 +1,4 @@ +export * from "./get_all_domains_tlds"; +export * from "./get_owned_all_domains"; +export * from "./get_owned_domains_for_tld"; +export * from "./resolve_domain"; diff --git a/src/tools/resolve_domain.ts b/src/tools/alldomains/resolve_domain.ts similarity index 94% rename from src/tools/resolve_domain.ts rename to src/tools/alldomains/resolve_domain.ts index 6de2206..3230e2b 100644 --- a/src/tools/resolve_domain.ts +++ b/src/tools/alldomains/resolve_domain.ts @@ -1,5 +1,5 @@ import { TldParser } from "@onsol/tldparser"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../agent"; import { PublicKey } from "@solana/web3.js"; /** diff --git a/src/tools/get_token_data.ts b/src/tools/dexscreener/get_token_data.ts similarity index 97% rename from src/tools/get_token_data.ts rename to src/tools/dexscreener/get_token_data.ts index 434aa9a..c4ec2ef 100644 --- a/src/tools/get_token_data.ts +++ b/src/tools/dexscreener/get_token_data.ts @@ -1,5 +1,5 @@ import { PublicKey } from "@solana/web3.js"; -import { JupiterTokenData } from "../types"; +import { JupiterTokenData } from "../../types"; export async function getTokenDataByAddress( mint: PublicKey, diff --git a/src/tools/dexscreener/index.ts b/src/tools/dexscreener/index.ts new file mode 100644 index 0000000..b9a3389 --- /dev/null +++ b/src/tools/dexscreener/index.ts @@ -0,0 +1 @@ +export * from "./get_token_data"; diff --git a/src/tools/flash_close_trade.ts b/src/tools/flash/flash_close_trade.ts similarity index 96% rename from src/tools/flash_close_trade.ts rename to src/tools/flash/flash_close_trade.ts index c30d0b6..cdd2b4f 100644 --- a/src/tools/flash_close_trade.ts +++ b/src/tools/flash/flash_close_trade.ts @@ -1,7 +1,7 @@ import { ComputeBudgetProgram } from "@solana/web3.js"; import { PoolConfig, Side } from "flash-sdk"; import { BN } from "@coral-xyz/anchor"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { CLOSE_POSITION_CU, marketSdkInfo, @@ -10,8 +10,8 @@ import { fetchOraclePrice, createPerpClient, get_flash_privilege, -} from "../utils/flashUtils"; -import { FlashCloseTradeParams } from "../types"; +} from "../../utils/flashUtils"; +import { FlashCloseTradeParams } from "../../types"; /** * Closes an existing position on Flash.Trade diff --git a/src/tools/flash_open_trade.ts b/src/tools/flash/flash_open_trade.ts similarity index 98% rename from src/tools/flash_open_trade.ts rename to src/tools/flash/flash_open_trade.ts index 6a646dc..5af7c60 100644 --- a/src/tools/flash_open_trade.ts +++ b/src/tools/flash/flash_open_trade.ts @@ -8,7 +8,7 @@ import { Custody, } from "flash-sdk"; import { BN } from "@coral-xyz/anchor"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { ALL_TOKENS, marketSdkInfo, @@ -18,8 +18,8 @@ import { fetchOraclePrice, createPerpClient, get_flash_privilege, -} from "../utils/flashUtils"; -import { FlashTradeParams } from "../types"; +} from "../../utils/flashUtils"; +import { FlashTradeParams } from "../../types"; /** * Opens a new position on Flash.Trade diff --git a/src/tools/flash/index.ts b/src/tools/flash/index.ts new file mode 100644 index 0000000..9ba0ee8 --- /dev/null +++ b/src/tools/flash/index.ts @@ -0,0 +1,2 @@ +export * from "./flash_open_trade"; +export * from "./flash_close_trade"; diff --git a/src/tools/create_gibwork_task.ts b/src/tools/gibwork/create_gibwork_task.ts similarity index 97% rename from src/tools/create_gibwork_task.ts rename to src/tools/gibwork/create_gibwork_task.ts index 40ff3c3..3c06f8b 100644 --- a/src/tools/create_gibwork_task.ts +++ b/src/tools/gibwork/create_gibwork_task.ts @@ -1,6 +1,6 @@ import { VersionedTransaction } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js"; -import { GibworkCreateTaskReponse, SolanaAgentKit } from "../index"; +import { GibworkCreateTaskReponse, SolanaAgentKit } from "../../index"; /** * Create an new task on Gibwork diff --git a/src/tools/gibwork/index.ts b/src/tools/gibwork/index.ts new file mode 100644 index 0000000..aa738b2 --- /dev/null +++ b/src/tools/gibwork/index.ts @@ -0,0 +1 @@ +export * from "./create_gibwork_task"; diff --git a/src/tools/index.ts b/src/tools/index.ts index 2363e3a..6ea6443 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,52 +1,25 @@ -export * from "./adrena_perp_trading"; -export * from "./create_gibwork_task"; -export * from "./create_image"; -export * from "./create_tiplinks"; -export * from "./deploy_collection"; -export * from "./deploy_token"; -export * from "./fetch_price"; -export * from "./get_all_domains_tlds"; -export * from "./get_all_registered_all_domains"; -export * from "./get_balance"; -export * from "./get_balance_other"; -export * from "./get_main_all_domains_domain"; -export * from "./get_owned_all_domains"; -export * from "./get_owned_domains_for_tld"; -export * from "./get_primary_domain"; -export * from "./get_token_data"; -export * from "./get_tps"; -export * from "./get_wallet_address"; -export * from "./launch_pumpfun_token"; -export * from "./lend"; -export * from "./manifest_trade"; -export * from "./mint_nft"; -export * from "./openbook_create_market"; -export * from "./orca_close_position"; -export * from "./orca_create_clmm"; -export * from "./orca_create_single_sided_liquidity_pool"; -export * from "./orca_fetch_positions"; -export * from "./orca_open_centered_position_with_liquidity"; -export * from "./orca_open_single_sided_position"; -export * from "./pyth_fetch_price"; -export * from "./raydium_create_ammV4"; -export * from "./raydium_create_clmm"; -export * from "./raydium_create_cpmm"; -export * from "./register_domain"; -export * from "./request_faucet_funds"; -export * from "./resolve_domain"; -export * from "./resolve_sol_domain"; -export * from "./rock_paper_scissor"; +export * from "./adrena"; +export * from "./sns"; +export * from "./dexscreener"; +export * from "./alldomains"; +export * from "./flash"; +export * from "./gibwork"; +export * from "./jupiter"; +export * from "./lulo"; +export * from "./manifest"; +export * from "./solana"; +export * from "./agent"; +export * from "./metaplex"; +export * from "./openbook"; +export * from "./orca"; +export * from "./pumpfun"; +export * from "./pyth"; +export * from "./raydium"; export * from "./rugcheck"; -export * from "./send_compressed_airdrop"; -export * from "./stake_with_jup"; -export * from "./stake_with_solayer"; -export * from "./tensor_trade"; - -export * from "./close_empty_token_accounts"; - -export * from "./trade"; -export * from "./transfer"; -export * from "./flash_open_trade"; -export * from "./flash_close_trade"; - -export * from "./create_3land_collectible"; +export * from "./sendarcade"; +export * from "./solayer"; +export * from "./tensor"; +export * from "./3land"; +export * from "./tiplink"; +export * from "./lightprotocol"; +export * from "./squads_multisig"; diff --git a/src/tools/fetch_price.ts b/src/tools/jupiter/fetch_price.ts similarity index 100% rename from src/tools/fetch_price.ts rename to src/tools/jupiter/fetch_price.ts diff --git a/src/tools/jupiter/index.ts b/src/tools/jupiter/index.ts new file mode 100644 index 0000000..6007331 --- /dev/null +++ b/src/tools/jupiter/index.ts @@ -0,0 +1,3 @@ +export * from "./fetch_price"; +export * from "./stake_with_jup"; +export * from "./trade"; diff --git a/src/tools/stake_with_jup.ts b/src/tools/jupiter/stake_with_jup.ts similarity index 97% rename from src/tools/stake_with_jup.ts rename to src/tools/jupiter/stake_with_jup.ts index c05915b..1db0955 100644 --- a/src/tools/stake_with_jup.ts +++ b/src/tools/jupiter/stake_with_jup.ts @@ -1,5 +1,5 @@ import { VersionedTransaction } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; /** * Stake SOL with Jup validator diff --git a/src/tools/trade.ts b/src/tools/jupiter/trade.ts similarity index 97% rename from src/tools/trade.ts rename to src/tools/jupiter/trade.ts index 4e11712..f4b2776 100644 --- a/src/tools/trade.ts +++ b/src/tools/jupiter/trade.ts @@ -1,11 +1,11 @@ import { VersionedTransaction, PublicKey } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { TOKENS, DEFAULT_OPTIONS, JUP_API, JUP_REFERRAL_ADDRESS, -} from "../constants"; +} from "../../constants"; import { getMint } from "@solana/spl-token"; /** * Swap tokens using Jupiter Exchange diff --git a/src/tools/lightprotocol/index.ts b/src/tools/lightprotocol/index.ts new file mode 100644 index 0000000..5de8804 --- /dev/null +++ b/src/tools/lightprotocol/index.ts @@ -0,0 +1 @@ +export * from "./send_compressed_airdrop"; diff --git a/src/tools/send_compressed_airdrop.ts b/src/tools/lightprotocol/send_compressed_airdrop.ts similarity index 99% rename from src/tools/send_compressed_airdrop.ts rename to src/tools/lightprotocol/send_compressed_airdrop.ts index 871c810..4d01ed6 100644 --- a/src/tools/send_compressed_airdrop.ts +++ b/src/tools/lightprotocol/send_compressed_airdrop.ts @@ -5,7 +5,7 @@ import { PublicKey, TransactionInstruction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { buildAndSignTx, calculateComputeUnitPrice, diff --git a/src/tools/lulo/index.ts b/src/tools/lulo/index.ts new file mode 100644 index 0000000..a28ed36 --- /dev/null +++ b/src/tools/lulo/index.ts @@ -0,0 +1 @@ +export * from "./lend"; diff --git a/src/tools/lend.ts b/src/tools/lulo/lend.ts similarity index 97% rename from src/tools/lend.ts rename to src/tools/lulo/lend.ts index 732f00c..9a6644c 100644 --- a/src/tools/lend.ts +++ b/src/tools/lulo/lend.ts @@ -1,5 +1,5 @@ import { VersionedTransaction } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; /** * Lend tokens for yields using Lulo diff --git a/src/tools/manifest/index.ts b/src/tools/manifest/index.ts new file mode 100644 index 0000000..d69980c --- /dev/null +++ b/src/tools/manifest/index.ts @@ -0,0 +1 @@ +export * from "./manifest_trade"; diff --git a/src/tools/manifest_trade.ts b/src/tools/manifest/manifest_trade.ts similarity index 99% rename from src/tools/manifest_trade.ts rename to src/tools/manifest/manifest_trade.ts index e65aef7..9ef1fb3 100644 --- a/src/tools/manifest_trade.ts +++ b/src/tools/manifest/manifest_trade.ts @@ -11,7 +11,7 @@ import { Transaction, TransactionInstruction, } from "@solana/web3.js"; -import { BatchOrderPattern, OrderParams, SolanaAgentKit } from "../index"; +import { BatchOrderPattern, OrderParams, SolanaAgentKit } from "../../index"; export async function manifestCreateMarket( agent: SolanaAgentKit, diff --git a/src/tools/deploy_collection.ts b/src/tools/metaplex/deploy_collection.ts similarity index 94% rename from src/tools/deploy_collection.ts rename to src/tools/metaplex/deploy_collection.ts index 10fef9d..0b981be 100644 --- a/src/tools/deploy_collection.ts +++ b/src/tools/metaplex/deploy_collection.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { generateSigner, keypairIdentity, @@ -9,7 +9,7 @@ import { mplCore, ruleSet, } from "@metaplex-foundation/mpl-core"; -import { CollectionOptions, CollectionDeployment } from "../types"; +import { CollectionOptions, CollectionDeployment } from "../../types"; import { fromWeb3JsKeypair, toWeb3JsPublicKey, diff --git a/src/tools/deploy_token.ts b/src/tools/metaplex/deploy_token.ts similarity index 97% rename from src/tools/deploy_token.ts rename to src/tools/metaplex/deploy_token.ts index 798e020..0f78743 100644 --- a/src/tools/deploy_token.ts +++ b/src/tools/metaplex/deploy_token.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { PublicKey } from "@solana/web3.js"; import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi"; diff --git a/src/tools/metaplex/index.ts b/src/tools/metaplex/index.ts new file mode 100644 index 0000000..7cdfe15 --- /dev/null +++ b/src/tools/metaplex/index.ts @@ -0,0 +1,3 @@ +export * from "./deploy_collection"; +export * from "./mint_nft"; +export * from "./deploy_token"; diff --git a/src/tools/mint_nft.ts b/src/tools/metaplex/mint_nft.ts similarity index 95% rename from src/tools/mint_nft.ts rename to src/tools/metaplex/mint_nft.ts index 4c25b91..dd6b68c 100644 --- a/src/tools/mint_nft.ts +++ b/src/tools/metaplex/mint_nft.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi"; import { create, mplCore } from "@metaplex-foundation/mpl-core"; import { fetchCollection } from "@metaplex-foundation/mpl-core"; @@ -9,7 +9,7 @@ import { toWeb3JsPublicKey, } from "@metaplex-foundation/umi-web3js-adapters"; import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; -import { MintCollectionNFTResponse } from "../types"; +import { MintCollectionNFTResponse } from "../../types"; /** * Mint a new NFT as part of an existing collection diff --git a/src/tools/openbook/index.ts b/src/tools/openbook/index.ts new file mode 100644 index 0000000..58d481e --- /dev/null +++ b/src/tools/openbook/index.ts @@ -0,0 +1 @@ +export * from "./openbook_create_market"; diff --git a/src/tools/openbook_create_market.ts b/src/tools/openbook/openbook_create_market.ts similarity index 96% rename from src/tools/openbook_create_market.ts rename to src/tools/openbook/openbook_create_market.ts index c7c12aa..1702ba3 100644 --- a/src/tools/openbook_create_market.ts +++ b/src/tools/openbook/openbook_create_market.ts @@ -5,7 +5,7 @@ import { } from "@raydium-io/raydium-sdk-v2"; import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; export async function openbookCreateMarket( agent: SolanaAgentKit, diff --git a/src/tools/orca/index.ts b/src/tools/orca/index.ts new file mode 100644 index 0000000..a405eb2 --- /dev/null +++ b/src/tools/orca/index.ts @@ -0,0 +1,6 @@ +export * from "./orca_close_position"; +export * from "./orca_create_clmm"; +export * from "./orca_create_single_sided_liquidity_pool"; +export * from "./orca_fetch_positions"; +export * from "./orca_open_centered_position_with_liquidity"; +export * from "./orca_open_single_sided_position"; diff --git a/src/tools/orca_close_position.ts b/src/tools/orca/orca_close_position.ts similarity index 95% rename from src/tools/orca_close_position.ts rename to src/tools/orca/orca_close_position.ts index 1f09403..95a0bf9 100644 --- a/src/tools/orca_close_position.ts +++ b/src/tools/orca/orca_close_position.ts @@ -4,15 +4,15 @@ import { TransactionMessage, VersionedTransaction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; -import { Wallet } from "../utils/keypair"; +import { SolanaAgentKit } from "../../agent"; +import { Wallet } from "../../utils/keypair"; import { ORCA_WHIRLPOOL_PROGRAM_ID, WhirlpoolContext, buildWhirlpoolClient, PDAUtil, } from "@orca-so/whirlpools-sdk"; -import { sendTx } from "../utils/send_tx"; +import { sendTx } from "../../utils/send_tx"; import { Percentage } from "@orca-so/common-sdk"; /** diff --git a/src/tools/orca_create_clmm.ts b/src/tools/orca/orca_create_clmm.ts similarity index 97% rename from src/tools/orca_create_clmm.ts rename to src/tools/orca/orca_create_clmm.ts index 8cbd81f..3e6d7a3 100644 --- a/src/tools/orca_create_clmm.ts +++ b/src/tools/orca/orca_create_clmm.ts @@ -4,8 +4,8 @@ import { TransactionMessage, VersionedTransaction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; -import { Wallet } from "../utils/keypair"; +import { SolanaAgentKit } from "../../agent"; +import { Wallet } from "../../utils/keypair"; import { Decimal } from "decimal.js"; import { ORCA_WHIRLPOOL_PROGRAM_ID, @@ -14,7 +14,7 @@ import { PoolUtil, buildWhirlpoolClient, } from "@orca-so/whirlpools-sdk"; -import { sendTx } from "../utils/send_tx"; +import { sendTx } from "../../utils/send_tx"; import { FEE_TIERS } from "./orca_create_single_sided_liquidity_pool"; /** diff --git a/src/tools/orca_create_single_sided_liquidity_pool.ts b/src/tools/orca/orca_create_single_sided_liquidity_pool.ts similarity index 99% rename from src/tools/orca_create_single_sided_liquidity_pool.ts rename to src/tools/orca/orca_create_single_sided_liquidity_pool.ts index f83df94..022489f 100644 --- a/src/tools/orca_create_single_sided_liquidity_pool.ts +++ b/src/tools/orca/orca_create_single_sided_liquidity_pool.ts @@ -4,9 +4,9 @@ import { TransactionMessage, VersionedTransaction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; import { BN } from "@coral-xyz/anchor"; -import { Wallet } from "../utils/keypair"; +import { Wallet } from "../../utils/keypair"; import { Decimal } from "decimal.js"; import { PDAUtil, @@ -37,7 +37,7 @@ import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, } from "@solana/spl-token"; -import { sendTx } from "../utils/send_tx"; +import { sendTx } from "../../utils/send_tx"; /** * Maps fee tier bps to their corresponding tick spacing values in the Orca Whirlpool protocol. diff --git a/src/tools/orca_fetch_positions.ts b/src/tools/orca/orca_fetch_positions.ts similarity index 98% rename from src/tools/orca_fetch_positions.ts rename to src/tools/orca/orca_fetch_positions.ts index f90b8a0..edeba5a 100644 --- a/src/tools/orca_fetch_positions.ts +++ b/src/tools/orca/orca_fetch_positions.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; import { Wallet } from "@coral-xyz/anchor"; import { ORCA_WHIRLPOOL_PROGRAM_ID, diff --git a/src/tools/orca_open_centered_position_with_liquidity.ts b/src/tools/orca/orca_open_centered_position_with_liquidity.ts similarity index 97% rename from src/tools/orca_open_centered_position_with_liquidity.ts rename to src/tools/orca/orca_open_centered_position_with_liquidity.ts index 9a2619d..dccf87b 100644 --- a/src/tools/orca_open_centered_position_with_liquidity.ts +++ b/src/tools/orca/orca_open_centered_position_with_liquidity.ts @@ -5,8 +5,8 @@ import { TransactionMessage, VersionedTransaction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; -import { Wallet } from "../utils/keypair"; +import { SolanaAgentKit } from "../../agent"; +import { Wallet } from "../../utils/keypair"; import { Decimal } from "decimal.js"; import { ORCA_WHIRLPOOL_PROGRAM_ID, @@ -18,7 +18,7 @@ import { NO_TOKEN_EXTENSION_CONTEXT, } from "@orca-so/whirlpools-sdk"; -import { sendTx } from "../utils/send_tx"; +import { sendTx } from "../../utils/send_tx"; import { Percentage } from "@orca-so/common-sdk"; import { TOKEN_2022_PROGRAM_ID } from "@solana/spl-token"; diff --git a/src/tools/orca_open_single_sided_position.ts b/src/tools/orca/orca_open_single_sided_position.ts similarity index 97% rename from src/tools/orca_open_single_sided_position.ts rename to src/tools/orca/orca_open_single_sided_position.ts index 6b95dfc..8a8e1e9 100644 --- a/src/tools/orca_open_single_sided_position.ts +++ b/src/tools/orca/orca_open_single_sided_position.ts @@ -5,8 +5,8 @@ import { TransactionMessage, VersionedTransaction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; -import { Wallet } from "../utils/keypair"; +import { SolanaAgentKit } from "../../agent"; +import { Wallet } from "../../utils/keypair"; import { Decimal } from "decimal.js"; import { ORCA_WHIRLPOOL_PROGRAM_ID, @@ -17,7 +17,7 @@ import { TokenExtensionContextForPool, NO_TOKEN_EXTENSION_CONTEXT, } from "@orca-so/whirlpools-sdk"; -import { sendTx } from "../utils/send_tx"; +import { sendTx } from "../../utils/send_tx"; import { Percentage } from "@orca-so/common-sdk"; import { TOKEN_2022_PROGRAM_ID } from "@solana/spl-token"; diff --git a/src/tools/pumpfun/index.ts b/src/tools/pumpfun/index.ts new file mode 100644 index 0000000..2d7cc24 --- /dev/null +++ b/src/tools/pumpfun/index.ts @@ -0,0 +1 @@ +export * from "./launch_pumpfun_token"; diff --git a/src/tools/launch_pumpfun_token.ts b/src/tools/pumpfun/launch_pumpfun_token.ts similarity index 99% rename from src/tools/launch_pumpfun_token.ts rename to src/tools/pumpfun/launch_pumpfun_token.ts index 08fd3bf..b18a05a 100644 --- a/src/tools/launch_pumpfun_token.ts +++ b/src/tools/pumpfun/launch_pumpfun_token.ts @@ -4,7 +4,7 @@ import { PumpfunLaunchResponse, PumpFunTokenOptions, SolanaAgentKit, -} from "../index"; +} from "../../index"; async function uploadMetadata( tokenName: string, diff --git a/src/tools/pyth/index.ts b/src/tools/pyth/index.ts new file mode 100644 index 0000000..118e222 --- /dev/null +++ b/src/tools/pyth/index.ts @@ -0,0 +1 @@ +export * from "./pyth_fetch_price"; diff --git a/src/tools/pyth_fetch_price.ts b/src/tools/pyth/pyth_fetch_price.ts similarity index 98% rename from src/tools/pyth_fetch_price.ts rename to src/tools/pyth/pyth_fetch_price.ts index 0946af4..ef5b6fa 100644 --- a/src/tools/pyth_fetch_price.ts +++ b/src/tools/pyth/pyth_fetch_price.ts @@ -1,5 +1,5 @@ import BN from "bn.js"; -import { PythPriceFeedIDItem } from "../types"; +import { PythPriceFeedIDItem } from "../../types"; /** * Fetch the price feed ID for a given token symbol from Pyth diff --git a/src/tools/raydium/index.ts b/src/tools/raydium/index.ts new file mode 100644 index 0000000..a116c1f --- /dev/null +++ b/src/tools/raydium/index.ts @@ -0,0 +1,3 @@ +export * from "./raydium_create_ammV4"; +export * from "./raydium_create_clmm"; +export * from "./raydium_create_cpmm"; diff --git a/src/tools/raydium_create_ammV4.ts b/src/tools/raydium/raydium_create_ammV4.ts similarity index 97% rename from src/tools/raydium_create_ammV4.ts rename to src/tools/raydium/raydium_create_ammV4.ts index 98f641e..1b5ce71 100644 --- a/src/tools/raydium_create_ammV4.ts +++ b/src/tools/raydium/raydium_create_ammV4.ts @@ -9,7 +9,7 @@ import { import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; export async function raydiumCreateAmmV4( agent: SolanaAgentKit, diff --git a/src/tools/raydium_create_clmm.ts b/src/tools/raydium/raydium_create_clmm.ts similarity index 97% rename from src/tools/raydium_create_clmm.ts rename to src/tools/raydium/raydium_create_clmm.ts index 7d049d4..611c2f1 100644 --- a/src/tools/raydium_create_clmm.ts +++ b/src/tools/raydium/raydium_create_clmm.ts @@ -7,7 +7,7 @@ import { MintLayout } from "@solana/spl-token"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import Decimal from "decimal.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; export async function raydiumCreateClmm( agent: SolanaAgentKit, diff --git a/src/tools/raydium_create_cpmm.ts b/src/tools/raydium/raydium_create_cpmm.ts similarity index 97% rename from src/tools/raydium_create_cpmm.ts rename to src/tools/raydium/raydium_create_cpmm.ts index 35c702d..59f1124 100644 --- a/src/tools/raydium_create_cpmm.ts +++ b/src/tools/raydium/raydium_create_cpmm.ts @@ -7,7 +7,7 @@ import { import { MintLayout } from "@solana/spl-token"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; export async function raydiumCreateCpmm( agent: SolanaAgentKit, diff --git a/src/tools/rugcheck/index.ts b/src/tools/rugcheck/index.ts new file mode 100644 index 0000000..0201430 --- /dev/null +++ b/src/tools/rugcheck/index.ts @@ -0,0 +1 @@ +export * from "./rugcheck"; diff --git a/src/tools/rugcheck.ts b/src/tools/rugcheck/rugcheck.ts similarity index 97% rename from src/tools/rugcheck.ts rename to src/tools/rugcheck/rugcheck.ts index 11d533d..923c0f5 100644 --- a/src/tools/rugcheck.ts +++ b/src/tools/rugcheck/rugcheck.ts @@ -1,4 +1,4 @@ -import { TokenCheck } from "../types"; +import { TokenCheck } from "../../types"; const BASE_URL = "https://api.rugcheck.xyz/v1"; diff --git a/src/tools/sendarcade/index.ts b/src/tools/sendarcade/index.ts new file mode 100644 index 0000000..5d09c37 --- /dev/null +++ b/src/tools/sendarcade/index.ts @@ -0,0 +1 @@ +export * from "./rock_paper_scissor"; diff --git a/src/tools/rock_paper_scissor.ts b/src/tools/sendarcade/rock_paper_scissor.ts similarity index 98% rename from src/tools/rock_paper_scissor.ts rename to src/tools/sendarcade/rock_paper_scissor.ts index 8a0603e..f2a48c2 100644 --- a/src/tools/rock_paper_scissor.ts +++ b/src/tools/sendarcade/rock_paper_scissor.ts @@ -1,5 +1,5 @@ import { sendAndConfirmTransaction, Transaction } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; export async function rock_paper_scissor( agent: SolanaAgentKit, diff --git a/src/tools/get_all_registered_all_domains.ts b/src/tools/sns/get_all_registered_all_domains.ts similarity index 89% rename from src/tools/get_all_registered_all_domains.ts rename to src/tools/sns/get_all_registered_all_domains.ts index 019a5ea..f6565b4 100644 --- a/src/tools/get_all_registered_all_domains.ts +++ b/src/tools/sns/get_all_registered_all_domains.ts @@ -1,7 +1,7 @@ import { getAllDomains } from "@bonfida/spl-name-service"; -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; import { PublicKey } from "@solana/web3.js"; -import { getAllDomainsTLDs } from "./get_all_domains_tlds"; +import { getAllDomainsTLDs } from "../alldomains/get_all_domains_tlds"; /** * Get all registered domains across all TLDs diff --git a/src/tools/get_main_all_domains_domain.ts b/src/tools/sns/get_main_all_domains_domain.ts similarity index 100% rename from src/tools/get_main_all_domains_domain.ts rename to src/tools/sns/get_main_all_domains_domain.ts diff --git a/src/tools/get_primary_domain.ts b/src/tools/sns/get_primary_domain.ts similarity index 96% rename from src/tools/get_primary_domain.ts rename to src/tools/sns/get_primary_domain.ts index 8e53f1d..ac0ff8f 100644 --- a/src/tools/get_primary_domain.ts +++ b/src/tools/sns/get_primary_domain.ts @@ -1,6 +1,6 @@ import { getPrimaryDomain as _getPrimaryDomain } from "@bonfida/spl-name-service"; import { PublicKey } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../agent"; /** * Retrieves the primary .sol domain associated with a given Solana public key. diff --git a/src/tools/sns/index.ts b/src/tools/sns/index.ts new file mode 100644 index 0000000..794ab31 --- /dev/null +++ b/src/tools/sns/index.ts @@ -0,0 +1,5 @@ +export * from "./get_all_registered_all_domains"; +export * from "./get_main_all_domains_domain"; +export * from "./get_primary_domain"; +export * from "./register_domain"; +export * from "./resolve_sol_domain"; diff --git a/src/tools/register_domain.ts b/src/tools/sns/register_domain.ts similarity index 94% rename from src/tools/register_domain.ts rename to src/tools/sns/register_domain.ts index 1348001..a747f2d 100644 --- a/src/tools/register_domain.ts +++ b/src/tools/sns/register_domain.ts @@ -1,8 +1,8 @@ import { registerDomainNameV2 } from "@bonfida/spl-name-service"; import { Transaction } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../agent"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; -import { TOKENS } from "../constants"; +import { TOKENS } from "../../constants"; /** * Register a .sol domain name using Bonfida Name Service diff --git a/src/tools/resolve_sol_domain.ts b/src/tools/sns/resolve_sol_domain.ts similarity index 95% rename from src/tools/resolve_sol_domain.ts rename to src/tools/sns/resolve_sol_domain.ts index 32b090b..9f87295 100644 --- a/src/tools/resolve_sol_domain.ts +++ b/src/tools/sns/resolve_sol_domain.ts @@ -1,6 +1,6 @@ import { resolve } from "@bonfida/spl-name-service"; import { PublicKey } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; /** * Resolves a .sol domain to a Solana PublicKey. diff --git a/src/tools/close_empty_token_accounts.ts b/src/tools/solana/close_empty_token_accounts.ts similarity index 98% rename from src/tools/close_empty_token_accounts.ts rename to src/tools/solana/close_empty_token_accounts.ts index 9a102db..a424b96 100644 --- a/src/tools/close_empty_token_accounts.ts +++ b/src/tools/solana/close_empty_token_accounts.ts @@ -3,7 +3,7 @@ import { Transaction, TransactionInstruction, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../agent"; +import { SolanaAgentKit } from "../../agent"; import { AccountLayout, createCloseAccountInstruction, diff --git a/src/tools/get_balance.ts b/src/tools/solana/get_balance.ts similarity index 94% rename from src/tools/get_balance.ts rename to src/tools/solana/get_balance.ts index a1e3736..36dbd36 100644 --- a/src/tools/get_balance.ts +++ b/src/tools/solana/get_balance.ts @@ -1,5 +1,5 @@ import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; /** * Get the balance of SOL or an SPL token for the agent's wallet diff --git a/src/tools/get_balance_other.ts b/src/tools/solana/get_balance_other.ts similarity index 97% rename from src/tools/get_balance_other.ts rename to src/tools/solana/get_balance_other.ts index 84c1c32..32df37c 100644 --- a/src/tools/get_balance_other.ts +++ b/src/tools/solana/get_balance_other.ts @@ -3,7 +3,7 @@ import { ParsedAccountData, PublicKey, } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; /** * Get the balance of SOL or an SPL token for the specified wallet address (other than the agent's wallet) diff --git a/src/tools/get_tps.ts b/src/tools/solana/get_tps.ts similarity index 90% rename from src/tools/get_tps.ts rename to src/tools/solana/get_tps.ts index 7314ce3..1c29a79 100644 --- a/src/tools/get_tps.ts +++ b/src/tools/solana/get_tps.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; export async function getTPS(agent: SolanaAgentKit): Promise { const perfSamples = await agent.connection.getRecentPerformanceSamples(); diff --git a/src/tools/solana/index.ts b/src/tools/solana/index.ts new file mode 100644 index 0000000..f9681a4 --- /dev/null +++ b/src/tools/solana/index.ts @@ -0,0 +1,6 @@ +export * from "./get_tps"; +export * from "./request_faucet_funds"; +export * from "./close_empty_token_accounts"; +export * from "./transfer"; +export * from "./get_balance"; +export * from "./get_balance_other"; diff --git a/src/tools/request_faucet_funds.ts b/src/tools/solana/request_faucet_funds.ts similarity index 93% rename from src/tools/request_faucet_funds.ts rename to src/tools/solana/request_faucet_funds.ts index bde8eed..3ce9111 100644 --- a/src/tools/request_faucet_funds.ts +++ b/src/tools/solana/request_faucet_funds.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { LAMPORTS_PER_SOL } from "@solana/web3.js"; /** diff --git a/src/tools/transfer.ts b/src/tools/solana/transfer.ts similarity index 97% rename from src/tools/transfer.ts rename to src/tools/solana/transfer.ts index 9e11dd7..04473d1 100644 --- a/src/tools/transfer.ts +++ b/src/tools/solana/transfer.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { PublicKey, SystemProgram, Transaction } from "@solana/web3.js"; import { LAMPORTS_PER_SOL } from "@solana/web3.js"; import { diff --git a/src/tools/solayer/index.ts b/src/tools/solayer/index.ts new file mode 100644 index 0000000..79dc074 --- /dev/null +++ b/src/tools/solayer/index.ts @@ -0,0 +1 @@ +export * from "./stake_with_solayer"; diff --git a/src/tools/stake_with_solayer.ts b/src/tools/solayer/stake_with_solayer.ts similarity index 97% rename from src/tools/stake_with_solayer.ts rename to src/tools/solayer/stake_with_solayer.ts index e2ef643..edbb8ff 100644 --- a/src/tools/stake_with_solayer.ts +++ b/src/tools/solayer/stake_with_solayer.ts @@ -1,5 +1,5 @@ import { VersionedTransaction } from "@solana/web3.js"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; /** * Stake SOL with Solayer diff --git a/src/tools/squads_multisig/index.ts b/src/tools/squads_multisig/index.ts new file mode 100644 index 0000000..5ceac36 --- /dev/null +++ b/src/tools/squads_multisig/index.ts @@ -0,0 +1,7 @@ +export * from "./approve_proposal"; +export * from "./create_multisig"; +export * from "./create_proposal"; +export * from "./deposit_to_multisig"; +export * from "./execute_proposal"; +export * from "./reject_proposal"; +export * from "./transfer_from_multisig"; diff --git a/src/tools/tensor/index.ts b/src/tools/tensor/index.ts new file mode 100644 index 0000000..574b361 --- /dev/null +++ b/src/tools/tensor/index.ts @@ -0,0 +1 @@ +export * from "./tensor_trade"; diff --git a/src/tools/tensor_trade.ts b/src/tools/tensor/tensor_trade.ts similarity index 98% rename from src/tools/tensor_trade.ts rename to src/tools/tensor/tensor_trade.ts index 4025ac3..b96069b 100644 --- a/src/tools/tensor_trade.ts +++ b/src/tools/tensor/tensor_trade.ts @@ -1,4 +1,4 @@ -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; import { TensorSwapSDK } from "@tensor-oss/tensorswap-sdk"; import { PublicKey, Transaction } from "@solana/web3.js"; import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; diff --git a/src/tools/create_tiplinks.ts b/src/tools/tiplink/create_tiplinks.ts similarity index 98% rename from src/tools/create_tiplinks.ts rename to src/tools/tiplink/create_tiplinks.ts index 20348ad..f38dbc1 100644 --- a/src/tools/create_tiplinks.ts +++ b/src/tools/tiplink/create_tiplinks.ts @@ -13,7 +13,7 @@ import { getMint, createAssociatedTokenAccountInstruction, } from "@solana/spl-token"; -import { SolanaAgentKit } from "../index"; +import { SolanaAgentKit } from "../../index"; const MINIMUM_SOL_BALANCE = 0.003 * LAMPORTS_PER_SOL; diff --git a/src/tools/tiplink/index.ts b/src/tools/tiplink/index.ts new file mode 100644 index 0000000..a5f83d2 --- /dev/null +++ b/src/tools/tiplink/index.ts @@ -0,0 +1 @@ +export * from "./create_tiplinks"; diff --git a/src/utils/keypair.ts b/src/utils/keypair.ts index 25d1a0e..1b62f1f 100644 --- a/src/utils/keypair.ts +++ b/src/utils/keypair.ts @@ -1,4 +1,9 @@ -import { Keypair, PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js"; +import { + Keypair, + PublicKey, + Transaction, + VersionedTransaction, +} from "@solana/web3.js"; import bs58 from "bs58"; export const keypair = Keypair.generate(); @@ -6,7 +11,6 @@ export const keypair = Keypair.generate(); console.log(keypair.publicKey.toString()); console.log(bs58.encode(keypair.secretKey)); - export class Wallet { private _signer: Keypair; @@ -14,7 +18,9 @@ export class Wallet { this._signer = signer; } - async signTransaction(tx: T): Promise { + async signTransaction( + tx: T, + ): Promise { if (tx instanceof Transaction) { tx.sign(this._signer); } else if (tx instanceof VersionedTransaction) { @@ -25,11 +31,13 @@ export class Wallet { return tx; } - async signAllTransactions(txs: T[]): Promise { + async signAllTransactions( + txs: T[], + ): Promise { return Promise.all(txs.map((tx) => this.signTransaction(tx))); } get publicKey(): PublicKey { return this._signer.publicKey; } -} \ No newline at end of file +}