Skip to content

Commit 3fff6c9

Browse files
Implement Jupiter Limit Order actions (#324)
# Pull Request Description This PR implements new actions and tools to create and manage limit orders using the Jupiter Limit API ## Changes Made This PR adds the following changes: - Added action and tool to create limit orders on Jupiter with given parameters - Added action and tool to get open limit orders on Jupiter - Added action and tool to cancel open limit orders on Jupiter - - Added action and tool to view order history on Jupiter ## Implementation Details - Used the Jupiter Limit API (https://api.jup.ag/limit/v2) to implement actions and tools for these functions ## Transaction executed by agent Example transaction: https://solscan.io/tx/4bXsLBwQ7HywUKTFSiABMQNJTCYDrNLFV4qLoqq9jbnWktLbijPC8poeTvA1MLtmtTiU2QsawDLcwzSLGB4dDKLv ## Prompt Used ``` - Create a Limit order on Solana to swap my USDC to SOL when SOL reaches $100 - Create a Limit order to sell 0.1 SOL when it reaches $300 - Cancel my open limit orders on Jupiter ``` ## Checklist - [x] I have tested these changes locally - [x] I have added a transaction link - [x] I have added the prompt used to test it
2 parents 86a6316 + eac0857 commit 3fff6c9

20 files changed

+794
-7
lines changed

src/actions/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ import getWormholeSupportedChainsAction from "./wormhole/getSupportedChains";
117117
import cctpTransferAction from "./wormhole/cctpTransfer";
118118
import createWrappedTokenAction from "./wormhole/createWrappedToken";
119119
import tokenTransferAction from "./wormhole/tokenTransfer";
120+
import getLimitOrderHistoryAction from "./jupiter/getLimitOrderHistory";
121+
import createLimitOrderAction from "./jupiter/createLimitOrder";
122+
import cancelLimitOrdersAction from "./jupiter/cancelLimitOrders";
123+
import getOpenLimitOrdersAction from "./jupiter/getOpenLimitOrders";
120124

121125
export const ACTIONS = {
122126
GET_INFO_ACTION: getInfoAction,
@@ -242,6 +246,10 @@ export const ACTIONS = {
242246
CCTP_TRANSFER_ACTION: cctpTransferAction,
243247
CREATE_WRAPPED_TOKEN_ACTION: createWrappedTokenAction,
244248
TOKEN_TRANSFER_ACTION: tokenTransferAction,
249+
CREATE_LIMIT_ORDER_ACTION: createLimitOrderAction,
250+
CANCEL_LIMIT_ORDERS_ACTION: cancelLimitOrdersAction,
251+
GET_LIMIT_ORDER_HISTORY_ACTION: getLimitOrderHistoryAction,
252+
GET_OPEN_LIMIT_ORDERS_ACTION: getOpenLimitOrdersAction,
245253
};
246254

247255
export type { Action, ActionExample, Handler } from "../types/action";
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { z } from "zod";
4+
import { cancelLimitOrders } from "../../tools/jupiter/cancel_limit_orders";
5+
6+
const cancelOrdersSchema = z.object({
7+
orders: z.array(z.string()).describe("The order public keys to cancel"),
8+
});
9+
10+
const cancelOrdersAction: Action = {
11+
name: "CANCEL_LIMIT_ORDERS",
12+
similes: [
13+
"abort orders",
14+
"cancel limit order",
15+
"revoke orders",
16+
"terminate orders",
17+
],
18+
description: "Cancels specified orders on the Solana blockchain.",
19+
examples: [
20+
[
21+
{
22+
input: {
23+
orders: ["GgMvwcfMz...ienihZvTmyBZYM", "HhNvwcfMz...Qa8ihZvTmyBZYN"],
24+
},
25+
output: {
26+
signatures: ["5K3N9...3J4", "6L4O0...4K5"],
27+
success: true,
28+
explanation: "Orders canceled successfully.",
29+
},
30+
explanation: "Successfully canceled the specified orders.",
31+
},
32+
{
33+
input: {
34+
orders: ["InvalidOrderKey"],
35+
},
36+
output: {
37+
signatures: [],
38+
success: false,
39+
error: "Error canceling orders: Invalid order key",
40+
explanation: "Failed to cancel orders due to invalid order key.",
41+
},
42+
explanation: "Failed to cancel orders due to an invalid order key.",
43+
},
44+
],
45+
],
46+
schema: cancelOrdersSchema,
47+
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
48+
const params = cancelOrdersSchema.parse(input);
49+
50+
try {
51+
const result = await cancelLimitOrders(agent, params);
52+
53+
return {
54+
status: "success",
55+
result,
56+
message: "Orders canceled successfully.",
57+
};
58+
} catch (error) {
59+
const errorMessage = `Error canceling orders: ${error}`;
60+
console.error(errorMessage);
61+
return {
62+
status: "error",
63+
message: errorMessage,
64+
};
65+
}
66+
},
67+
};
68+
69+
export default cancelOrdersAction;
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { z } from "zod";
4+
import { createLimitOrder } from "../../tools/jupiter/create_limit_order";
5+
6+
const createLimitOrderSchema = z.object({
7+
inputMint: z.string(),
8+
outputMint: z.string(),
9+
params: z.object({
10+
makingAmount: z.string(),
11+
takingAmount: z.string(),
12+
expiredAt: z.string().optional(),
13+
}),
14+
});
15+
16+
export const createLimitOrderAction: Action = {
17+
name: "CREATE_LIMIT_ORDER",
18+
similes: ["place limit order", "submit limit order", "create trading order"],
19+
description: "Creates and sends a limit order on the Solana blockchain.",
20+
examples: [
21+
[
22+
{
23+
input: {
24+
inputAmount: "5500000",
25+
outputAmount: "50000000",
26+
},
27+
output: {
28+
signature: "5K3N9...3J4",
29+
order: "order123",
30+
success: true,
31+
explanation: "Order created and sent successfully.",
32+
},
33+
explanation:
34+
"Successfully created a limit order with specified amounts.",
35+
},
36+
{
37+
input: {
38+
inputAmount: "1000000",
39+
outputAmount: "20000000",
40+
},
41+
output: {
42+
signature: "",
43+
order: "",
44+
success: false,
45+
error: "Error creating and sending limit order: Network error",
46+
explanation: "Failed to create and send the order.",
47+
},
48+
explanation: "Failed to create a limit order due to a network error.",
49+
},
50+
],
51+
],
52+
schema: createLimitOrderSchema,
53+
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
54+
const params = createLimitOrderSchema.parse(input);
55+
56+
try {
57+
const result = await createLimitOrder(agent, params);
58+
59+
return {
60+
status: "success",
61+
result,
62+
message: `Order created and sent successfully.`,
63+
};
64+
} catch (error) {
65+
return {
66+
status: "error",
67+
message: `Failed to create limit order: ${error}`,
68+
};
69+
}
70+
},
71+
};
72+
73+
export default createLimitOrderAction;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { z } from "zod";
4+
import { getLimitOrderHistory } from "../../tools/jupiter/get_limit_order_history";
5+
6+
const getLimitOrderHistoryAction: Action = {
7+
name: "GET_LIMIT_ORDER_HISTORY",
8+
similes: [
9+
"fetch order history",
10+
"get limit order history",
11+
"retrieve order history",
12+
"get past orders",
13+
],
14+
description: "Fetches the limit order history for a given wallet.",
15+
examples: [
16+
[
17+
{
18+
input: {
19+
walletPublicKey: "CmwPTro4ogHPhuG9Dozx1X7KiATNudF1rkem3BQmuPn7",
20+
page: 1,
21+
},
22+
output: {
23+
history: {
24+
orders: [
25+
{
26+
userPubkey: "CmwPTro4ogHPhuG9Dozx1X7KiATNudF1rkem3BQmuPn7",
27+
orderKey: "GgMvwcfMzP9AmfwZuMzNienXGBhQa8dksihZvTmyBZYM",
28+
inputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
29+
outputMint: "So11111111111111111111111111111111111111112",
30+
makingAmount: "10000000",
31+
takingAmount: "50000000",
32+
remainingMakingAmount: "50000000",
33+
remainingTakingAmount: "10000000",
34+
expiredAt: null,
35+
createdAt: "2023-10-01T00:00:00Z",
36+
updatedAt: "2023-10-02T00:00:00Z",
37+
status: "Open",
38+
openTx:
39+
"https://solscan.io/tx/2431GhdanFFwWg...77BBCSk34SW2iFHwu17zQARjr",
40+
closeTx: "",
41+
programVersion: "1.0",
42+
trades: [
43+
{
44+
amount: "10000000",
45+
price: "50000000",
46+
timestamp: "2023-10-01T01:00:00Z",
47+
},
48+
],
49+
},
50+
],
51+
hasMoreData: false,
52+
page: 1,
53+
},
54+
success: true,
55+
},
56+
explanation: "Successfully fetched order history for the given wallet.",
57+
},
58+
],
59+
],
60+
schema: z.object({}),
61+
handler: async (agent: SolanaAgentKit) => {
62+
try {
63+
const history = await getLimitOrderHistory(agent);
64+
return {
65+
status: "success",
66+
result: { history, success: true },
67+
message: "Successfully fetched order history for the given wallet.",
68+
};
69+
} catch (error) {
70+
const errorMessage = `Error fetching order history: ${error}`;
71+
console.error(errorMessage);
72+
return {
73+
status: "error",
74+
message: errorMessage,
75+
result: { history: [], success: false },
76+
};
77+
}
78+
},
79+
};
80+
81+
export default getLimitOrderHistoryAction;
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Action } from "../../types/action";
2+
import { SolanaAgentKit } from "../../agent";
3+
import { getOpenLimitOrders } from "../../tools/jupiter/get_open_limit_orders";
4+
import { z } from "zod";
5+
6+
const getOpenLimitOrdersAction: Action = {
7+
name: "GET_OPEN_LIMIT_ORDERS",
8+
similes: ["fetch open orders", "get limit orders", "retrieve open orders"],
9+
description: "Fetches the open limit orders for a given wallet.",
10+
examples: [
11+
[
12+
{
13+
input: {
14+
walletPublicKey: "CmwPTro4ogHP...muPn7",
15+
},
16+
output: {
17+
orders: [
18+
{
19+
userPubkey: "CmwPTro4ogHP...muPn7",
20+
orderKey: "GgMvwcfM...vTmyBZYM",
21+
inputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
22+
outputMint: "So11111111111111111111111111111111111111112",
23+
makingAmount: "10000000",
24+
takingAmount: "50000000",
25+
remainingMakingAmount: "50000000",
26+
remainingTakingAmount: "10000000",
27+
expiredAt: null,
28+
createdAt: "2023-10-01T00:00:00Z",
29+
updatedAt: "2023-10-02T00:00:00Z",
30+
status: "Open",
31+
openTx:
32+
"https://solscan.io/tx/2431GhdanFFwWg...77BBCSk34SW2iFHwu17zQARjr",
33+
closeTx: "",
34+
programVersion: "1.0",
35+
trades: [
36+
{
37+
amount: "10000000",
38+
price: "50000000",
39+
timestamp: "2023-10-01T01:00:00Z",
40+
},
41+
],
42+
},
43+
],
44+
success: true,
45+
},
46+
explanation: "Successfully fetched open orders for the given wallet.",
47+
},
48+
],
49+
],
50+
schema: z.object({}),
51+
handler: async (agent: SolanaAgentKit) => {
52+
try {
53+
const orders = await getOpenLimitOrders(agent);
54+
return {
55+
status: "success",
56+
result: { orders, success: true },
57+
message: "Successfully fetched open orders for the given wallet.",
58+
};
59+
} catch (error) {
60+
const errorMessage = `Error fetching open orders: ${error}`;
61+
console.error(errorMessage);
62+
return {
63+
status: "error",
64+
message: errorMessage,
65+
result: { orders: [], success: false },
66+
};
67+
}
68+
},
69+
};
70+
71+
export default getOpenLimitOrdersAction;

src/agent/index.ts

+40-1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ import {
170170
CctpTransferInput,
171171
TokenTransferInput,
172172
CreateWrappedTokenInput,
173+
CreateJupiterOrderRequest,
174+
CancelJupiterOrderRequest,
173175
} from "../types";
174176
import {
175177
DasApiAsset,
@@ -187,14 +189,17 @@ import {
187189
getTrendingTokensUsingElfaAi,
188190
getSmartTwitterAccountStats,
189191
} from "../tools/elfa_ai";
190-
import { Chain, TokenId } from "@wormhole-foundation/sdk/dist/cjs";
191192
import {
192193
getQuote as getOkxQuote,
193194
executeSwap as executeOkxSwapTool,
194195
getTokens,
195196
getChainData,
196197
getLiquidity,
197198
} from "../tools/okx-dex";
199+
import { createLimitOrder } from "../tools/jupiter/create_limit_order";
200+
import { cancelLimitOrders } from "../tools/jupiter/cancel_limit_orders";
201+
import { getOpenLimitOrders } from "../tools/jupiter/get_open_limit_orders";
202+
import { getLimitOrderHistory } from "../tools/jupiter/get_limit_order_history";
198203

199204
/**
200205
* Main class for interacting with Solana blockchain
@@ -1390,4 +1395,38 @@ export class SolanaAgentKit {
13901395
async getOkxChainData() {
13911396
return getChainData(this);
13921397
}
1398+
1399+
/**
1400+
* Create a limit order on Jupiter
1401+
* @param params Parameters for creating the limit order
1402+
* @returns Result of the limit order creation
1403+
*/
1404+
async createJupiterLimitOrder(params: CreateJupiterOrderRequest) {
1405+
return createLimitOrder(this, params);
1406+
}
1407+
1408+
/**
1409+
* Cancel limit orders on Jupiter
1410+
* @param params Parameters for canceling the orders
1411+
* @returns Result of the order cancellation
1412+
*/
1413+
async cancelJupiterLimitOrders(params: CancelJupiterOrderRequest) {
1414+
return cancelLimitOrders(this, params);
1415+
}
1416+
1417+
/**
1418+
* Get open limit orders on Jupiter
1419+
* @returns List of open limit orders
1420+
*/
1421+
async getOpenJupiterLimitOrders() {
1422+
return getOpenLimitOrders(this);
1423+
}
1424+
1425+
/**
1426+
* Get limit order history on Jupiter
1427+
* @returns Limit order history
1428+
*/
1429+
async getJupiterLimitOrderHistory() {
1430+
return getLimitOrderHistory(this);
1431+
}
13931432
}

0 commit comments

Comments
 (0)