@gala-chain/launchpad-mcp-server 1.23.1 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +34 -6
- package/dist/constants/mcpToolNames.d.ts +6 -2
- package/dist/constants/mcpToolNames.d.ts.map +1 -1
- package/dist/constants/mcpToolNames.js +4 -2
- package/dist/constants/mcpToolNames.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/prompts/explore-dex-pools.d.ts +20 -0
- package/dist/prompts/explore-dex-pools.d.ts.map +1 -0
- package/dist/prompts/explore-dex-pools.js +132 -0
- package/dist/prompts/explore-dex-pools.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -2
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +6 -3
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/pools.js.map +1 -1
- package/dist/tools/dex/fetchAllDexPools.d.ts +9 -0
- package/dist/tools/dex/fetchAllDexPools.d.ts.map +1 -0
- package/dist/tools/dex/fetchAllDexPools.js +45 -0
- package/dist/tools/dex/fetchAllDexPools.js.map +1 -0
- package/dist/tools/dex/fetchDexPools.d.ts +9 -0
- package/dist/tools/dex/fetchDexPools.d.ts.map +1 -0
- package/dist/tools/dex/fetchDexPools.js +58 -0
- package/dist/tools/dex/fetchDexPools.js.map +1 -0
- package/dist/tools/dex/index.d.ts +4 -3
- package/dist/tools/dex/index.d.ts.map +1 -1
- package/dist/tools/dex/index.js +9 -4
- package/dist/tools/dex/index.js.map +1 -1
- package/docs/AI-AGENT-PATTERNS.md +555 -0
- package/docs/CONSTRAINTS-REFERENCE.md +454 -0
- package/docs/PROMPT-TOOL-MAPPING.md +352 -0
- package/docs/examples/default-values-pattern.md +240 -0
- package/docs/examples/tool-factory-pattern.md +217 -0
- package/jest.config.js +94 -0
- package/package.json +3 -3
- package/src/__tests__/integration/fetchTokenDetails.integration.test.ts +258 -0
- package/src/__tests__/integration/poolTools.integration.test.ts +185 -0
- package/src/__tests__/server.test.ts +255 -0
- package/src/constants/mcpToolNames.ts +183 -0
- package/src/index.ts +19 -0
- package/src/prompts/__tests__/promptStructure.test.ts +187 -0
- package/src/prompts/__tests__/registry.test.ts +349 -0
- package/src/prompts/analysis.ts +380 -0
- package/src/prompts/balances.ts +182 -0
- package/src/prompts/create-token.ts +123 -0
- package/src/prompts/creation-utils.ts +103 -0
- package/src/prompts/dex-trading.ts +86 -0
- package/src/prompts/discover-tokens.ts +86 -0
- package/src/prompts/explore-dex-pools.ts +138 -0
- package/src/prompts/index.ts +178 -0
- package/src/prompts/liquidity-positions.ts +237 -0
- package/src/prompts/pools.ts +496 -0
- package/src/prompts/portfolio.ts +208 -0
- package/src/prompts/social.ts +94 -0
- package/src/prompts/trading-calculations.ts +414 -0
- package/src/prompts/trading.ts +160 -0
- package/src/prompts/transfers.ts +97 -0
- package/src/prompts/utility-tools.ts +266 -0
- package/src/prompts/utility.ts +77 -0
- package/src/prompts/utils/handlerHelpers.ts +55 -0
- package/src/prompts/utils/textTemplates.ts +73 -0
- package/src/prompts/utils/workflowTemplates.ts +511 -0
- package/src/schemas/common-schemas.ts +393 -0
- package/src/scripts/test-all-prompts.ts +184 -0
- package/src/server.ts +367 -0
- package/src/tools/__tests__/dex-tools.test.ts +562 -0
- package/src/tools/__tests__/liquidity-positions.test.ts +673 -0
- package/src/tools/balance/index.ts +174 -0
- package/src/tools/creation/index.ts +182 -0
- package/src/tools/dex/fetchAllDexPools.ts +45 -0
- package/src/tools/dex/fetchDexPools.ts +58 -0
- package/src/tools/dex/index.ts +231 -0
- package/src/tools/dex/liquidity-positions.ts +547 -0
- package/src/tools/index.ts +94 -0
- package/src/tools/pools/fetchAllPools.ts +47 -0
- package/src/tools/pools/fetchAllPriceHistory.ts +119 -0
- package/src/tools/pools/fetchPoolDetails.ts +27 -0
- package/src/tools/pools/fetchPoolDetailsForCalculation.ts +22 -0
- package/src/tools/pools/fetchPools.ts +47 -0
- package/src/tools/pools/fetchPriceHistory.ts +124 -0
- package/src/tools/pools/fetchTokenDetails.ts +77 -0
- package/src/tools/pools/index.ts +284 -0
- package/src/tools/social/index.ts +64 -0
- package/src/tools/trading/index.ts +605 -0
- package/src/tools/transfers/index.ts +75 -0
- package/src/tools/utils/clearCache.ts +36 -0
- package/src/tools/utils/createWallet.ts +19 -0
- package/src/tools/utils/explainSdkUsage.ts +1446 -0
- package/src/tools/utils/getAddress.ts +12 -0
- package/src/tools/utils/getCacheInfo.ts +14 -0
- package/src/tools/utils/getConfig.ts +21 -0
- package/src/tools/utils/getEnvironment.ts +17 -0
- package/src/tools/utils/getEthereumAddress.ts +12 -0
- package/src/tools/utils/getUrlByTokenName.ts +12 -0
- package/src/tools/utils/getVersion.ts +25 -0
- package/src/tools/utils/getWallet.ts +25 -0
- package/src/tools/utils/hasWallet.ts +15 -0
- package/src/tools/utils/index.ts +37 -0
- package/src/tools/utils/isTokenGraduated.ts +16 -0
- package/src/tools/utils/setWallet.ts +41 -0
- package/src/tools/utils/switchEnvironment.ts +28 -0
- package/src/types/mcp.ts +72 -0
- package/src/utils/__tests__/validation.test.ts +147 -0
- package/src/utils/constraints.ts +155 -0
- package/src/utils/default-values.ts +208 -0
- package/src/utils/error-handler.ts +69 -0
- package/src/utils/error-templates.ts +273 -0
- package/src/utils/response-formatter.ts +51 -0
- package/src/utils/tool-factory.ts +303 -0
- package/src/utils/tool-registry.ts +296 -0
- package/src/utils/validation.ts +429 -0
- package/tests/wallet-management-integration.test.ts +284 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DEX Liquidity Position Management Tools
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing liquidity positions on GalaSwap DEX, including:
|
|
5
|
+
* - Querying user positions and position details
|
|
6
|
+
* - Estimating liquidity removal
|
|
7
|
+
* - Adding liquidity by price or tick range
|
|
8
|
+
* - Removing liquidity and collecting fees
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { MCPTool } from '../../types/mcp.js';
|
|
12
|
+
import { formatSuccess } from '../../utils/response-formatter.js';
|
|
13
|
+
import { withErrorHandling } from '../../utils/error-handler.js';
|
|
14
|
+
import {
|
|
15
|
+
DECIMAL_AMOUNT_SCHEMA,
|
|
16
|
+
ADDRESS_SCHEMA,
|
|
17
|
+
} from '../../schemas/common-schemas.js';
|
|
18
|
+
|
|
19
|
+
// Token symbol for DEX trading
|
|
20
|
+
const TOKEN_SYMBOL_SCHEMA = {
|
|
21
|
+
type: 'string',
|
|
22
|
+
minLength: 1,
|
|
23
|
+
maxLength: 20,
|
|
24
|
+
description: 'Token symbol (e.g., "GALA", "GUSDC")',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Fee tier for GalaSwap (in basis points)
|
|
28
|
+
const FEE_TIER_SCHEMA = {
|
|
29
|
+
type: 'number',
|
|
30
|
+
enum: [500, 3000, 10000],
|
|
31
|
+
description: 'Fee tier in basis points: 500 (0.05%), 3000 (0.30%), 10000 (1.00%)',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// 1. Get User Liquidity Positions
|
|
35
|
+
export const getUserLiquidityPositionsTool: MCPTool = {
|
|
36
|
+
name: 'gala_launchpad_get_user_liquidity_positions',
|
|
37
|
+
description:
|
|
38
|
+
'Get all open liquidity positions for a wallet address with optional pagination',
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
ownerAddress: {
|
|
43
|
+
...ADDRESS_SCHEMA,
|
|
44
|
+
description: 'Wallet address to query positions for (e.g., "0x1234..." or "eth|1234...")',
|
|
45
|
+
},
|
|
46
|
+
limit: {
|
|
47
|
+
type: 'number',
|
|
48
|
+
minimum: 1,
|
|
49
|
+
maximum: 100,
|
|
50
|
+
description: 'Maximum number of positions to return (optional)',
|
|
51
|
+
},
|
|
52
|
+
bookmark: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
description: 'Pagination bookmark from previous response (optional)',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ['ownerAddress'],
|
|
58
|
+
},
|
|
59
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
60
|
+
const positions = await sdk.getSwapUserLiquidityPositions(
|
|
61
|
+
args.ownerAddress,
|
|
62
|
+
args.limit,
|
|
63
|
+
args.bookmark
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return formatSuccess({
|
|
67
|
+
ownerAddress: args.ownerAddress,
|
|
68
|
+
positionCount: (positions && Array.isArray(positions)) ? positions.length : 0,
|
|
69
|
+
positions: (positions && Array.isArray(positions))
|
|
70
|
+
? positions.map((pos: any) => ({
|
|
71
|
+
positionId: pos.positionId,
|
|
72
|
+
token0: pos.token0,
|
|
73
|
+
token1: pos.token1,
|
|
74
|
+
feeTier: pos.feeTier,
|
|
75
|
+
liquidity: pos.liquidity,
|
|
76
|
+
amount0: pos.amount0,
|
|
77
|
+
amount1: pos.amount1,
|
|
78
|
+
feeAmount0: pos.feeAmount0,
|
|
79
|
+
feeAmount1: pos.feeAmount1,
|
|
80
|
+
tickLower: pos.tickLower,
|
|
81
|
+
tickUpper: pos.tickUpper,
|
|
82
|
+
}))
|
|
83
|
+
: [],
|
|
84
|
+
message:
|
|
85
|
+
(positions && Array.isArray(positions))
|
|
86
|
+
? `${positions.length} open positions found`
|
|
87
|
+
: 'No open positions found',
|
|
88
|
+
});
|
|
89
|
+
}),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// 2. Get Liquidity Position by ID
|
|
93
|
+
export const getLiquidityPositionByIdTool: MCPTool = {
|
|
94
|
+
name: 'gala_launchpad_get_liquidity_position_by_id',
|
|
95
|
+
description: 'Get specific liquidity position details by position ID',
|
|
96
|
+
inputSchema: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: {
|
|
99
|
+
ownerAddress: {
|
|
100
|
+
...ADDRESS_SCHEMA,
|
|
101
|
+
description: 'Wallet address that owns the position',
|
|
102
|
+
},
|
|
103
|
+
positionId: {
|
|
104
|
+
type: 'string',
|
|
105
|
+
minLength: 1,
|
|
106
|
+
description: 'Unique position identifier',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
required: ['ownerAddress', 'positionId'],
|
|
110
|
+
},
|
|
111
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
112
|
+
const position = await sdk.getSwapLiquidityPositionById(args.ownerAddress, args.positionId);
|
|
113
|
+
|
|
114
|
+
if (!position) {
|
|
115
|
+
return formatSuccess({
|
|
116
|
+
found: false,
|
|
117
|
+
message: `Position ${args.positionId} not found`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return formatSuccess({
|
|
122
|
+
found: true,
|
|
123
|
+
positionId: position.positionId,
|
|
124
|
+
ownerAddress: position.ownerAddress,
|
|
125
|
+
token0: position.token0,
|
|
126
|
+
token1: position.token1,
|
|
127
|
+
feeTier: position.feeTier,
|
|
128
|
+
liquidity: position.liquidity,
|
|
129
|
+
amount0: position.amount0,
|
|
130
|
+
amount1: position.amount1,
|
|
131
|
+
feeAmount0: position.feeAmount0,
|
|
132
|
+
feeAmount1: position.feeAmount1,
|
|
133
|
+
tickLower: position.tickLower,
|
|
134
|
+
tickUpper: position.tickUpper,
|
|
135
|
+
createdAt: position.createdAt ? new Date(position.createdAt).toISOString() : undefined,
|
|
136
|
+
updatedAt: position.updatedAt ? new Date(position.updatedAt).toISOString() : undefined,
|
|
137
|
+
message: `Position ${args.positionId}: ${position.liquidity} liquidity in ${position.token0}/${position.token1}`,
|
|
138
|
+
});
|
|
139
|
+
}),
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// 3. Get Liquidity Position by Token Pair
|
|
143
|
+
export const getLiquidityPositionTool: MCPTool = {
|
|
144
|
+
name: 'gala_launchpad_get_liquidity_position',
|
|
145
|
+
description:
|
|
146
|
+
'Get liquidity position for a specific token pair and price range (tick boundaries)',
|
|
147
|
+
inputSchema: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {
|
|
150
|
+
ownerAddress: {
|
|
151
|
+
...ADDRESS_SCHEMA,
|
|
152
|
+
description: 'Wallet address that owns the position',
|
|
153
|
+
},
|
|
154
|
+
token0: TOKEN_SYMBOL_SCHEMA,
|
|
155
|
+
token1: TOKEN_SYMBOL_SCHEMA,
|
|
156
|
+
fee: FEE_TIER_SCHEMA,
|
|
157
|
+
tickLower: {
|
|
158
|
+
type: 'number',
|
|
159
|
+
description: 'Lower tick boundary of the position',
|
|
160
|
+
},
|
|
161
|
+
tickUpper: {
|
|
162
|
+
type: 'number',
|
|
163
|
+
description: 'Upper tick boundary of the position',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
required: ['ownerAddress', 'token0', 'token1', 'fee', 'tickLower', 'tickUpper'],
|
|
167
|
+
},
|
|
168
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
169
|
+
const position = await sdk.getSwapLiquidityPosition(args.ownerAddress, {
|
|
170
|
+
token0: args.token0,
|
|
171
|
+
token1: args.token1,
|
|
172
|
+
fee: args.fee,
|
|
173
|
+
tickLower: args.tickLower,
|
|
174
|
+
tickUpper: args.tickUpper,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
if (!position) {
|
|
178
|
+
return formatSuccess({
|
|
179
|
+
found: false,
|
|
180
|
+
message: `No position found for ${args.token0}/${args.token1} at ticks ${args.tickLower}-${args.tickUpper}`,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return formatSuccess({
|
|
185
|
+
found: true,
|
|
186
|
+
positionId: position.positionId,
|
|
187
|
+
token0: position.token0,
|
|
188
|
+
token1: position.token1,
|
|
189
|
+
feeTier: position.feeTier,
|
|
190
|
+
liquidity: position.liquidity,
|
|
191
|
+
amount0: position.amount0,
|
|
192
|
+
amount1: position.amount1,
|
|
193
|
+
feeAmount0: position.feeAmount0,
|
|
194
|
+
feeAmount1: position.feeAmount1,
|
|
195
|
+
tickLower: position.tickLower,
|
|
196
|
+
tickUpper: position.tickUpper,
|
|
197
|
+
message: `Found position: ${position.liquidity} liquidity with ${position.feeAmount0} ${args.token0} and ${position.feeAmount1} ${args.token1} in fees`,
|
|
198
|
+
});
|
|
199
|
+
}),
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// 4. Estimate Liquidity Removal
|
|
203
|
+
export const estimateRemoveLiquidityTool: MCPTool = {
|
|
204
|
+
name: 'gala_launchpad_estimate_remove_liquidity',
|
|
205
|
+
description:
|
|
206
|
+
'Estimate tokens and fees received when removing liquidity at current market prices',
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
token0: TOKEN_SYMBOL_SCHEMA,
|
|
211
|
+
token1: TOKEN_SYMBOL_SCHEMA,
|
|
212
|
+
fee: FEE_TIER_SCHEMA,
|
|
213
|
+
liquidity: {
|
|
214
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
215
|
+
description: 'Liquidity amount to estimate removal for',
|
|
216
|
+
},
|
|
217
|
+
tickLower: {
|
|
218
|
+
type: 'number',
|
|
219
|
+
description: 'Lower tick boundary of the position',
|
|
220
|
+
},
|
|
221
|
+
tickUpper: {
|
|
222
|
+
type: 'number',
|
|
223
|
+
description: 'Upper tick boundary of the position',
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
required: ['token0', 'token1', 'fee', 'liquidity', 'tickLower', 'tickUpper'],
|
|
227
|
+
},
|
|
228
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
229
|
+
const estimate = await sdk.getSwapEstimateRemoveLiquidity({
|
|
230
|
+
token0: args.token0,
|
|
231
|
+
token1: args.token1,
|
|
232
|
+
fee: args.fee,
|
|
233
|
+
liquidity: args.liquidity,
|
|
234
|
+
tickLower: args.tickLower,
|
|
235
|
+
tickUpper: args.tickUpper,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
return formatSuccess({
|
|
239
|
+
liquidity: estimate.liquidity,
|
|
240
|
+
amount0: estimate.amount0,
|
|
241
|
+
amount1: estimate.amount1,
|
|
242
|
+
fee0: estimate.fee0,
|
|
243
|
+
fee1: estimate.fee1,
|
|
244
|
+
token0Symbol: estimate.token0Symbol,
|
|
245
|
+
token1Symbol: estimate.token1Symbol,
|
|
246
|
+
tickLower: estimate.tickLower,
|
|
247
|
+
tickUpper: estimate.tickUpper,
|
|
248
|
+
currentPrice: estimate.currentPrice,
|
|
249
|
+
message: `Removing ${args.liquidity} liquidity would return ${estimate.amount0} ${args.token0} + ${estimate.amount1} ${args.token1}, plus ${estimate.fee0} ${args.token0} and ${estimate.fee1} ${args.token1} in fees`,
|
|
250
|
+
});
|
|
251
|
+
}),
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// 5. Add Liquidity by Price Range
|
|
255
|
+
export const addLiquidityByPriceTool: MCPTool = {
|
|
256
|
+
name: 'gala_launchpad_add_liquidity_by_price',
|
|
257
|
+
description:
|
|
258
|
+
'Add liquidity to a pool by specifying min/max price boundaries (SDK calculates tick boundaries)',
|
|
259
|
+
inputSchema: {
|
|
260
|
+
type: 'object',
|
|
261
|
+
properties: {
|
|
262
|
+
token0: TOKEN_SYMBOL_SCHEMA,
|
|
263
|
+
token1: TOKEN_SYMBOL_SCHEMA,
|
|
264
|
+
fee: FEE_TIER_SCHEMA,
|
|
265
|
+
minPrice: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
description: 'Minimum price boundary (e.g., "0.90")',
|
|
268
|
+
},
|
|
269
|
+
maxPrice: {
|
|
270
|
+
type: 'string',
|
|
271
|
+
description: 'Maximum price boundary (e.g., "1.10")',
|
|
272
|
+
},
|
|
273
|
+
amount0Desired: {
|
|
274
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
275
|
+
description: 'Desired amount of token0 to provide',
|
|
276
|
+
},
|
|
277
|
+
amount1Desired: {
|
|
278
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
279
|
+
description: 'Desired amount of token1 to provide',
|
|
280
|
+
},
|
|
281
|
+
amount0Min: {
|
|
282
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
283
|
+
description: 'Minimum acceptable amount0 (optional, defaults to 0)',
|
|
284
|
+
},
|
|
285
|
+
amount1Min: {
|
|
286
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
287
|
+
description: 'Minimum acceptable amount1 (optional, defaults to 0)',
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
required: [
|
|
291
|
+
'token0',
|
|
292
|
+
'token1',
|
|
293
|
+
'fee',
|
|
294
|
+
'minPrice',
|
|
295
|
+
'maxPrice',
|
|
296
|
+
'amount0Desired',
|
|
297
|
+
'amount1Desired',
|
|
298
|
+
],
|
|
299
|
+
},
|
|
300
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
301
|
+
// Validate wallet before execution
|
|
302
|
+
try {
|
|
303
|
+
sdk.getAddress();
|
|
304
|
+
} catch {
|
|
305
|
+
throw new Error('Wallet not configured - required for adding liquidity');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const result = await sdk.addSwapLiquidityByPrice({
|
|
309
|
+
token0: args.token0,
|
|
310
|
+
token1: args.token1,
|
|
311
|
+
fee: args.fee,
|
|
312
|
+
minPrice: args.minPrice,
|
|
313
|
+
maxPrice: args.maxPrice,
|
|
314
|
+
amount0Desired: args.amount0Desired,
|
|
315
|
+
amount1Desired: args.amount1Desired,
|
|
316
|
+
amount0Min: args.amount0Min || '0',
|
|
317
|
+
amount1Min: args.amount1Min || '0',
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
return formatSuccess({
|
|
321
|
+
transactionId: result.transactionId || result.id,
|
|
322
|
+
status: result.status,
|
|
323
|
+
token0: args.token0,
|
|
324
|
+
token1: args.token1,
|
|
325
|
+
priceRange: `${args.minPrice} - ${args.maxPrice}`,
|
|
326
|
+
amount0: result.amount0 || args.amount0Desired,
|
|
327
|
+
amount1: result.amount1 || args.amount1Desired,
|
|
328
|
+
liquidity: result.liquidity,
|
|
329
|
+
positionId: result.positionId,
|
|
330
|
+
message: `Liquidity added! Position: ${result.positionId || result.transactionId}`,
|
|
331
|
+
});
|
|
332
|
+
}),
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// 6. Add Liquidity by Tick Range
|
|
336
|
+
export const addLiquidityByTicksTool: MCPTool = {
|
|
337
|
+
name: 'gala_launchpad_add_liquidity_by_ticks',
|
|
338
|
+
description:
|
|
339
|
+
'Add liquidity to a pool by specifying exact tick boundaries (advanced usage)',
|
|
340
|
+
inputSchema: {
|
|
341
|
+
type: 'object',
|
|
342
|
+
properties: {
|
|
343
|
+
token0: TOKEN_SYMBOL_SCHEMA,
|
|
344
|
+
token1: TOKEN_SYMBOL_SCHEMA,
|
|
345
|
+
feeTier: FEE_TIER_SCHEMA,
|
|
346
|
+
tickLower: {
|
|
347
|
+
type: 'number',
|
|
348
|
+
description: 'Lower tick boundary (must be multiple of tickSpacing)',
|
|
349
|
+
},
|
|
350
|
+
tickUpper: {
|
|
351
|
+
type: 'number',
|
|
352
|
+
description: 'Upper tick boundary (must be multiple of tickSpacing)',
|
|
353
|
+
},
|
|
354
|
+
amount0Desired: {
|
|
355
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
356
|
+
description: 'Desired amount of token0 to provide',
|
|
357
|
+
},
|
|
358
|
+
amount1Desired: {
|
|
359
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
360
|
+
description: 'Desired amount of token1 to provide',
|
|
361
|
+
},
|
|
362
|
+
amount0Min: {
|
|
363
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
364
|
+
description: 'Minimum acceptable amount0 (optional, defaults to 0)',
|
|
365
|
+
},
|
|
366
|
+
amount1Min: {
|
|
367
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
368
|
+
description: 'Minimum acceptable amount1 (optional, defaults to 0)',
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
required: [
|
|
372
|
+
'token0',
|
|
373
|
+
'token1',
|
|
374
|
+
'feeTier',
|
|
375
|
+
'tickLower',
|
|
376
|
+
'tickUpper',
|
|
377
|
+
'amount0Desired',
|
|
378
|
+
'amount1Desired',
|
|
379
|
+
],
|
|
380
|
+
},
|
|
381
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
382
|
+
// Validate wallet before execution
|
|
383
|
+
try {
|
|
384
|
+
sdk.getAddress();
|
|
385
|
+
} catch {
|
|
386
|
+
throw new Error('Wallet not configured - required for adding liquidity');
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const result = await sdk.addSwapLiquidityByTicks({
|
|
390
|
+
token0: args.token0,
|
|
391
|
+
token1: args.token1,
|
|
392
|
+
feeTier: args.feeTier,
|
|
393
|
+
tickLower: args.tickLower,
|
|
394
|
+
tickUpper: args.tickUpper,
|
|
395
|
+
amount0Desired: args.amount0Desired,
|
|
396
|
+
amount1Desired: args.amount1Desired,
|
|
397
|
+
amount0Min: args.amount0Min || '0',
|
|
398
|
+
amount1Min: args.amount1Min || '0',
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
return formatSuccess({
|
|
402
|
+
transactionId: result.transactionId || result.id,
|
|
403
|
+
status: result.status,
|
|
404
|
+
token0: args.token0,
|
|
405
|
+
token1: args.token1,
|
|
406
|
+
tickRange: `${args.tickLower} - ${args.tickUpper}`,
|
|
407
|
+
amount0: result.amount0 || args.amount0Desired,
|
|
408
|
+
amount1: result.amount1 || args.amount1Desired,
|
|
409
|
+
liquidity: result.liquidity,
|
|
410
|
+
positionId: result.positionId,
|
|
411
|
+
message: `Liquidity added! Position: ${result.positionId || result.transactionId}`,
|
|
412
|
+
});
|
|
413
|
+
}),
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
// 7. Remove Liquidity
|
|
417
|
+
export const removeLiquidityTool: MCPTool = {
|
|
418
|
+
name: 'gala_launchpad_remove_liquidity',
|
|
419
|
+
description:
|
|
420
|
+
'Remove liquidity from an open position and withdraw underlying tokens',
|
|
421
|
+
inputSchema: {
|
|
422
|
+
type: 'object',
|
|
423
|
+
properties: {
|
|
424
|
+
ownerAddress: {
|
|
425
|
+
...ADDRESS_SCHEMA,
|
|
426
|
+
description: 'Wallet address that owns the position',
|
|
427
|
+
},
|
|
428
|
+
positionId: {
|
|
429
|
+
type: 'string',
|
|
430
|
+
minLength: 1,
|
|
431
|
+
description: 'Position identifier to remove liquidity from',
|
|
432
|
+
},
|
|
433
|
+
liquidity: {
|
|
434
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
435
|
+
description: 'Amount of liquidity to remove (full liquidity to close position)',
|
|
436
|
+
},
|
|
437
|
+
amount0Min: {
|
|
438
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
439
|
+
description: 'Minimum acceptable amount of token0 to receive',
|
|
440
|
+
},
|
|
441
|
+
amount1Min: {
|
|
442
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
443
|
+
description: 'Minimum acceptable amount of token1 to receive',
|
|
444
|
+
},
|
|
445
|
+
deadline: {
|
|
446
|
+
type: 'number',
|
|
447
|
+
description: 'Transaction deadline (unix timestamp, optional)',
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
required: ['ownerAddress', 'positionId', 'liquidity', 'amount0Min', 'amount1Min'],
|
|
451
|
+
},
|
|
452
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
453
|
+
// Validate wallet before execution
|
|
454
|
+
try {
|
|
455
|
+
sdk.getAddress();
|
|
456
|
+
} catch {
|
|
457
|
+
throw new Error('Wallet not configured - required for removing liquidity');
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const deadline = args.deadline || Math.floor(Date.now() / 1000) + 60 * 20; // 20 minute default
|
|
461
|
+
|
|
462
|
+
const result = await sdk.removeSwapLiquidity({
|
|
463
|
+
ownerAddress: args.ownerAddress,
|
|
464
|
+
positionId: args.positionId,
|
|
465
|
+
liquidity: args.liquidity,
|
|
466
|
+
amount0Min: args.amount0Min,
|
|
467
|
+
amount1Min: args.amount1Min,
|
|
468
|
+
deadline,
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
return formatSuccess({
|
|
472
|
+
transactionId: result.transactionId || result.id,
|
|
473
|
+
status: result.status,
|
|
474
|
+
positionId: args.positionId,
|
|
475
|
+
liquidity: args.liquidity,
|
|
476
|
+
amount0: result.amount0,
|
|
477
|
+
amount1: result.amount1,
|
|
478
|
+
message: `Liquidity removed! Received ${result.amount0} token0 and ${result.amount1} token1`,
|
|
479
|
+
});
|
|
480
|
+
}),
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// 8. Collect Position Fees
|
|
484
|
+
export const collectPositionFeesTool: MCPTool = {
|
|
485
|
+
name: 'gala_launchpad_collect_position_fees',
|
|
486
|
+
description:
|
|
487
|
+
'Collect accumulated trading fees from a liquidity position without modifying the position',
|
|
488
|
+
inputSchema: {
|
|
489
|
+
type: 'object',
|
|
490
|
+
properties: {
|
|
491
|
+
ownerAddress: {
|
|
492
|
+
...ADDRESS_SCHEMA,
|
|
493
|
+
description: 'Wallet address that owns the position',
|
|
494
|
+
},
|
|
495
|
+
positionId: {
|
|
496
|
+
type: 'string',
|
|
497
|
+
minLength: 1,
|
|
498
|
+
description: 'Position identifier to collect fees from',
|
|
499
|
+
},
|
|
500
|
+
amount0Max: {
|
|
501
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
502
|
+
description: 'Maximum amount of token0 fees to collect (optional)',
|
|
503
|
+
},
|
|
504
|
+
amount1Max: {
|
|
505
|
+
...DECIMAL_AMOUNT_SCHEMA,
|
|
506
|
+
description: 'Maximum amount of token1 fees to collect (optional)',
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
required: ['ownerAddress', 'positionId'],
|
|
510
|
+
},
|
|
511
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
512
|
+
// Validate wallet before execution
|
|
513
|
+
try {
|
|
514
|
+
sdk.getAddress();
|
|
515
|
+
} catch {
|
|
516
|
+
throw new Error('Wallet not configured - required for collecting fees');
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const result = await sdk.collectSwapPositionFees({
|
|
520
|
+
ownerAddress: args.ownerAddress,
|
|
521
|
+
positionId: args.positionId,
|
|
522
|
+
amount0Max: args.amount0Max,
|
|
523
|
+
amount1Max: args.amount1Max,
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
return formatSuccess({
|
|
527
|
+
transactionId: result.transactionId || result.id,
|
|
528
|
+
status: result.status,
|
|
529
|
+
positionId: args.positionId,
|
|
530
|
+
amount0Collected: result.amount0,
|
|
531
|
+
amount1Collected: result.amount1,
|
|
532
|
+
message: `Fees collected! ${result.amount0} token0 and ${result.amount1} token1 harvested`,
|
|
533
|
+
});
|
|
534
|
+
}),
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
// Export all liquidity position tools
|
|
538
|
+
export const liquidityPositionTools: MCPTool[] = [
|
|
539
|
+
getUserLiquidityPositionsTool,
|
|
540
|
+
getLiquidityPositionByIdTool,
|
|
541
|
+
getLiquidityPositionTool,
|
|
542
|
+
estimateRemoveLiquidityTool,
|
|
543
|
+
addLiquidityByPriceTool,
|
|
544
|
+
addLiquidityByTicksTool,
|
|
545
|
+
removeLiquidityTool,
|
|
546
|
+
collectPositionFeesTool,
|
|
547
|
+
];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Registry
|
|
3
|
+
*
|
|
4
|
+
* Enhanced tool registry with auto-validation and metadata.
|
|
5
|
+
* Uses tool-registry system for robust tool management.
|
|
6
|
+
*
|
|
7
|
+
* @see src/utils/tool-registry.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { poolTools } from './pools/index.js';
|
|
11
|
+
import { tradingTools } from './trading/index.js';
|
|
12
|
+
import { dexTools } from './dex/index.js';
|
|
13
|
+
import { balanceTools } from './balance/index.js';
|
|
14
|
+
import { creationTools } from './creation/index.js';
|
|
15
|
+
import { socialTools } from './social/index.js';
|
|
16
|
+
import { transferTools } from './transfers/index.js';
|
|
17
|
+
import { utilityTools } from './utils/index.js';
|
|
18
|
+
import { createToolRegistry, logToolRegistry } from '../utils/tool-registry.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Tool categories with metadata
|
|
22
|
+
*/
|
|
23
|
+
const toolCategories = [
|
|
24
|
+
{
|
|
25
|
+
name: 'pools',
|
|
26
|
+
description: 'Pool management, pricing, and token availability checks',
|
|
27
|
+
tools: poolTools,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'trading',
|
|
31
|
+
description: 'Token trading operations (buy, sell, calculate amounts)',
|
|
32
|
+
tools: tradingTools,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'dex',
|
|
36
|
+
description: 'DEX/GalaSwap trading for graduated tokens (NEW in v3.23.0)',
|
|
37
|
+
tools: dexTools,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'balance',
|
|
41
|
+
description: 'Balance queries and portfolio management',
|
|
42
|
+
tools: balanceTools,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'creation',
|
|
46
|
+
description: 'Token creation and launch operations',
|
|
47
|
+
tools: creationTools,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'social',
|
|
51
|
+
description: 'Comments and social interactions',
|
|
52
|
+
tools: socialTools,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'transfers',
|
|
56
|
+
description: 'Token and GALA transfer operations',
|
|
57
|
+
tools: transferTools,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'utils',
|
|
61
|
+
description: 'Utility tools (wallet, config, SDK documentation)',
|
|
62
|
+
tools: utilityTools,
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Enhanced tool registry with validation (72 tools total):
|
|
68
|
+
* - Pools: 17 tools
|
|
69
|
+
* - Trading: 13 tools
|
|
70
|
+
* - DEX/GalaSwap: 13 tools (5 swap + 8 liquidity)
|
|
71
|
+
* - Balance: 6 tools
|
|
72
|
+
* - Creation: 4 tools
|
|
73
|
+
* - Social: 2 tools
|
|
74
|
+
* - Transfers: 2 tools
|
|
75
|
+
* - Utilities: 15 tools (config, version, environment switching, wallet mgmt, etc.)
|
|
76
|
+
*/
|
|
77
|
+
export const registry = createToolRegistry(toolCategories, 72);
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Complete tool array (for backward compatibility)
|
|
81
|
+
*/
|
|
82
|
+
export const tools = registry.tools;
|
|
83
|
+
|
|
84
|
+
// Log registry statistics in debug mode
|
|
85
|
+
if (process.env.DEBUG === 'true') {
|
|
86
|
+
logToolRegistry(registry);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Throw error if registry is invalid
|
|
90
|
+
if (!registry.isValid) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Tool registry validation failed:\n${registry.errors.join('\n')}`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch All Pools Tool
|
|
3
|
+
*
|
|
4
|
+
* Convenience tool that fetches all available pools with automatic pagination.
|
|
5
|
+
* Equivalent to calling fetchPools with limit: 0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { MCPTool } from '../../types/mcp.js';
|
|
9
|
+
import { formatSuccess } from '../../utils/response-formatter.js';
|
|
10
|
+
import { withErrorHandling } from '../../utils/error-handler.js';
|
|
11
|
+
|
|
12
|
+
export const fetchAllPoolsTool: MCPTool = {
|
|
13
|
+
name: 'gala_launchpad_fetch_all_pools',
|
|
14
|
+
description: 'Fetch all available pools with automatic pagination. No page/limit parameters needed - returns ALL pools matching filters.',
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
search: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
minLength: 1,
|
|
21
|
+
maxLength: 100,
|
|
22
|
+
description: 'Optional search query (fuzzy match filter)',
|
|
23
|
+
},
|
|
24
|
+
tokenName: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
minLength: 3,
|
|
27
|
+
maxLength: 20,
|
|
28
|
+
pattern: '^[a-zA-Z0-9]{3,20}$',
|
|
29
|
+
description: 'Optional token name (exact match filter)',
|
|
30
|
+
},
|
|
31
|
+
type: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
enum: ['recent', 'popular'],
|
|
34
|
+
description: 'Type of pools to fetch (default: recent)',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
handler: withErrorHandling(async (sdk, args) => {
|
|
39
|
+
const result = await sdk.fetchAllPools({
|
|
40
|
+
...(args.search && { search: args.search }),
|
|
41
|
+
...(args.tokenName && { tokenName: args.tokenName }),
|
|
42
|
+
...(args.type && { type: args.type }),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return formatSuccess(result);
|
|
46
|
+
}),
|
|
47
|
+
};
|