diff --git a/README.md b/README.md
index 78259f9..f4d5562 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,7 @@ Anyone - whether an SF-based AI researcher or a crypto-native builder - can brin
- Launch on Pump via PumpPortal
- Raydium pool creation (CPMM, CLMM, AMMv4)
- Orca Whirlpool integration
+ - Manifest market creation, and limit orders
- Meteora Dynamic AMM, DLMM Pool, and Alpha Vault
- Openbook market creation
- Register and Resolve SNS
diff --git a/docs/index.html b/docs/index.html
index 8fecca2..97d0e78 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -46,6 +46,7 @@
Launch on Pump via PumpPortal
Raydium pool creation (CPMM, CLMM, AMMv4)
Orca Whirlpool integration
+Manifest market creation, and limit orders
Meteora Dynamic AMM, DLMM Pool, and Alpha Vault
Openbook market creation
Register and Resolve SNS
diff --git a/package.json b/package.json
index 3f5de39..7f0769f 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
"license": "Apache-2.0",
"dependencies": {
"@bonfida/spl-name-service": "^3.0.7",
+ "@cks-systems/manifest-sdk": "^0.1.73",
"@coral-xyz/anchor": "0.29",
"@langchain/core": "^0.3.26",
"@langchain/groq": "^0.1.2",
diff --git a/src/agent/index.ts b/src/agent/index.ts
index 5d146a1..4acf694 100644
--- a/src/agent/index.ts
+++ b/src/agent/index.ts
@@ -15,12 +15,16 @@ import {
lendAsset,
mintCollectionNFT,
openbookCreateMarket,
+ manifestCreateMarket,
raydiumCreateAmmV4,
raydiumCreateClmm,
raydiumCreateCpmm,
registerDomain,
request_faucet_funds,
trade,
+ limitOrder,
+ cancelAllOrders,
+ withdrawAll,
transfer,
getTokenDataByAddress,
getTokenDataByTicker,
@@ -171,6 +175,23 @@ export class SolanaAgentKit {
return trade(this, outputMint, inputAmount, inputMint, slippageBps);
}
+ async limitOrder(
+ marketId: PublicKey,
+ quantity: number,
+ side: string,
+ price: number,
+ ): Promise {
+ return limitOrder(this, marketId, quantity, side, price);
+ }
+
+ async cancelAllOrders(marketId: PublicKey): Promise {
+ return cancelAllOrders(this, marketId);
+ }
+
+ async withdrawAll(marketId: PublicKey): Promise {
+ return withdrawAll(this, marketId);
+ }
+
async lendAssets(amount: number): Promise {
return lendAsset(this, amount);
}
@@ -397,6 +418,13 @@ export class SolanaAgentKit {
);
}
+ async manifestCreateMarket(
+ baseMint: PublicKey,
+ quoteMint: PublicKey,
+ ): Promise {
+ return manifestCreateMarket(this, baseMint, quoteMint);
+ }
+
async pythFetchPrice(priceFeedID: string): Promise {
return pythFetchPrice(priceFeedID);
}
diff --git a/src/langchain/index.ts b/src/langchain/index.ts
index e044c3b..4605fd3 100644
--- a/src/langchain/index.ts
+++ b/src/langchain/index.ts
@@ -306,6 +306,114 @@ export class SolanaTradeTool extends Tool {
}
}
+export class SolanaLimitOrderTool extends Tool {
+ name = "solana_limit_order";
+ description = `This tool can be used to place limit orders using Manifest.
+
+ 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 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)";
@@ -1252,6 +1360,44 @@ export class SolanaOpenbookCreateMarket extends Tool {
}
}
+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
@@ -1705,6 +1851,10 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaRaydiumCreateClmm(solanaKit),
new SolanaRaydiumCreateCpmm(solanaKit),
new SolanaOpenbookCreateMarket(solanaKit),
+ new SolanaManifestCreateMarket(solanaKit),
+ new SolanaLimitOrderTool(solanaKit),
+ new SolanaCancelAllOrdersTool(solanaKit),
+ new SolanaWithdrawAllTool(solanaKit),
new SolanaClosePosition(solanaKit),
new SolanaOrcaCreateCLMM(solanaKit),
new SolanaOrcaCreateSingleSideLiquidityPool(solanaKit),
diff --git a/src/tools/cancel_all_orders.ts b/src/tools/cancel_all_orders.ts
new file mode 100644
index 0000000..d8e3639
--- /dev/null
+++ b/src/tools/cancel_all_orders.ts
@@ -0,0 +1,37 @@
+import {
+ PublicKey,
+ sendAndConfirmTransaction,
+ Transaction,
+} from "@solana/web3.js";
+import { SolanaAgentKit } from "../index";
+import { ManifestClient } from "@cks-systems/manifest-sdk";
+
+/**
+ * Cancels all orders from Manifest
+ * @param agent SolanaAgentKit instance
+ * @param marketId Public key for the manifest market
+ * @returns Transaction signature
+ */
+export async function cancelAllOrders(
+ agent: SolanaAgentKit,
+ marketId: PublicKey,
+): Promise {
+ try {
+ const mfxClient = await ManifestClient.getClientForMarket(
+ agent.connection,
+ marketId,
+ agent.wallet,
+ );
+
+ const cancelAllOrdersIx = await mfxClient.cancelAllIx();
+ const signature = await sendAndConfirmTransaction(
+ agent.connection,
+ new Transaction().add(cancelAllOrdersIx),
+ [agent.wallet],
+ );
+
+ return signature;
+ } catch (error: any) {
+ throw new Error(`Cancel all orders failed: ${error.message}`);
+ }
+}
diff --git a/src/tools/index.ts b/src/tools/index.ts
index c1584de..b9f7542 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -6,6 +6,9 @@ export * from "./get_balance_other";
export * from "./mint_nft";
export * from "./transfer";
export * from "./trade";
+export * from "./limit_order";
+export * from "./cancel_all_orders";
+export * from "./withdraw_all";
export * from "./register_domain";
export * from "./resolve_sol_domain";
export * from "./get_primary_domain";
@@ -40,6 +43,7 @@ export * from "./raydium_create_ammV4";
export * from "./raydium_create_clmm";
export * from "./raydium_create_cpmm";
export * from "./openbook_create_market";
+export * from "./manifest_create_market";
export * from "./pyth_fetch_price";
export * from "./create_gibwork_task";
diff --git a/src/tools/limit_order.ts b/src/tools/limit_order.ts
new file mode 100644
index 0000000..ad05bf6
--- /dev/null
+++ b/src/tools/limit_order.ts
@@ -0,0 +1,61 @@
+import {
+ PublicKey,
+ Transaction,
+ sendAndConfirmTransaction,
+ TransactionInstruction,
+} from "@solana/web3.js";
+import { SolanaAgentKit } from "../index";
+import {
+ ManifestClient,
+ WrapperPlaceOrderParamsExternal,
+} from "@cks-systems/manifest-sdk";
+import { OrderType } from "@cks-systems/manifest-sdk/client/ts/src/wrapper/types/OrderType";
+
+/**
+ * Place limit orders using Manifest
+ * @param agent SolanaAgentKit instance
+ * @param marketId Public key for the manifest market
+ * @param quantity Amount to trade in tokens
+ * @param side Buy or Sell
+ * @param price Price in tokens ie. SOL/USDC
+ * @returns Transaction signature
+ */
+export async function limitOrder(
+ agent: SolanaAgentKit,
+ marketId: PublicKey,
+ quantity: number,
+ side: string,
+ price: number,
+): Promise {
+ try {
+ const mfxClient = await ManifestClient.getClientForMarket(
+ agent.connection,
+ marketId,
+ agent.wallet,
+ );
+
+ const orderParams: WrapperPlaceOrderParamsExternal = {
+ numBaseTokens: quantity,
+ tokenPrice: price,
+ isBid: side === "Buy",
+ lastValidSlot: 0,
+ orderType: OrderType.Limit,
+ clientOrderId: Number(Math.random() * 1000),
+ };
+
+ const depositPlaceOrderIx: TransactionInstruction[] =
+ await mfxClient.placeOrderWithRequiredDepositIx(
+ agent.wallet.publicKey,
+ orderParams,
+ );
+ const signature = await sendAndConfirmTransaction(
+ agent.connection,
+ new Transaction().add(...depositPlaceOrderIx),
+ [agent.wallet],
+ );
+
+ return signature;
+ } catch (error: any) {
+ throw new Error(`Limit Order failed: ${error.message}`);
+ }
+}
diff --git a/src/tools/manifest_create_market.ts b/src/tools/manifest_create_market.ts
new file mode 100644
index 0000000..e0960f4
--- /dev/null
+++ b/src/tools/manifest_create_market.ts
@@ -0,0 +1,43 @@
+import { ManifestClient } from "@cks-systems/manifest-sdk";
+import {
+ Keypair,
+ PublicKey,
+ sendAndConfirmTransaction,
+ SystemProgram,
+ Transaction,
+ TransactionInstruction,
+} from "@solana/web3.js";
+import { SolanaAgentKit } from "../index";
+
+export async function manifestCreateMarket(
+ agent: SolanaAgentKit,
+ baseMint: PublicKey,
+ quoteMint: PublicKey,
+): Promise {
+ const marketKeypair: Keypair = Keypair.generate();
+ const FIXED_MANIFEST_HEADER_SIZE: number = 256;
+ const createAccountIx: TransactionInstruction = SystemProgram.createAccount({
+ fromPubkey: agent.wallet.publicKey,
+ newAccountPubkey: marketKeypair.publicKey,
+ space: FIXED_MANIFEST_HEADER_SIZE,
+ lamports: await agent.connection.getMinimumBalanceForRentExemption(
+ FIXED_MANIFEST_HEADER_SIZE,
+ ),
+ programId: new PublicKey("MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"),
+ });
+ const createMarketIx = ManifestClient["createMarketIx"](
+ agent.wallet.publicKey,
+ baseMint,
+ quoteMint,
+ marketKeypair.publicKey,
+ );
+
+ const tx: Transaction = new Transaction();
+ tx.add(createAccountIx);
+ tx.add(createMarketIx);
+ const signature = await sendAndConfirmTransaction(agent.connection, tx, [
+ agent.wallet,
+ marketKeypair,
+ ]);
+ return [signature, marketKeypair.publicKey.toBase58()];
+}
diff --git a/src/tools/withdraw_all.ts b/src/tools/withdraw_all.ts
new file mode 100644
index 0000000..99e3bc1
--- /dev/null
+++ b/src/tools/withdraw_all.ts
@@ -0,0 +1,37 @@
+import {
+ PublicKey,
+ sendAndConfirmTransaction,
+ Transaction,
+} from "@solana/web3.js";
+import { SolanaAgentKit } from "../index";
+import { ManifestClient } from "@cks-systems/manifest-sdk";
+
+/**
+ * Withdraws all funds from Manifest
+ * @param agent SolanaAgentKit instance
+ * @param marketId Public key for the manifest market
+ * @returns Transaction signature
+ */
+export async function withdrawAll(
+ agent: SolanaAgentKit,
+ marketId: PublicKey,
+): Promise {
+ try {
+ const mfxClient = await ManifestClient.getClientForMarket(
+ agent.connection,
+ marketId,
+ agent.wallet,
+ );
+
+ const withdrawAllIx = await mfxClient.withdrawAllIx();
+ const signature = await sendAndConfirmTransaction(
+ agent.connection,
+ new Transaction().add(...withdrawAllIx),
+ [agent.wallet],
+ );
+
+ return signature;
+ } catch (error: any) {
+ throw new Error(`Withdraw all failed: ${error.message}`);
+ }
+}