@gala-chain/launchpad-mcp-server 1.22.0 → 1.22.2
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 +24 -0
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/package.json +2 -2
- package/docs/AI-AGENT-PATTERNS.md +0 -555
- package/docs/CONSTRAINTS-REFERENCE.md +0 -454
- package/docs/PROMPT-TOOL-MAPPING.md +0 -352
- package/docs/examples/default-values-pattern.md +0 -240
- package/docs/examples/tool-factory-pattern.md +0 -217
- package/jest.config.js +0 -94
- package/src/__tests__/integration/fetchTokenDetails.integration.test.ts +0 -258
- package/src/__tests__/integration/poolTools.integration.test.ts +0 -185
- package/src/constants/mcpToolNames.ts +0 -141
- package/src/index.ts +0 -19
- package/src/prompts/__tests__/promptStructure.test.ts +0 -137
- package/src/prompts/__tests__/registry.test.ts +0 -191
- package/src/prompts/analysis.ts +0 -429
- package/src/prompts/create-token.ts +0 -123
- package/src/prompts/dex-trading.ts +0 -86
- package/src/prompts/discover-tokens.ts +0 -86
- package/src/prompts/index.ts +0 -154
- package/src/prompts/liquidity-positions.ts +0 -270
- package/src/prompts/portfolio.ts +0 -242
- package/src/prompts/trading.ts +0 -191
- package/src/prompts/utility.ts +0 -43
- package/src/prompts/utils/workflowTemplates.ts +0 -511
- package/src/schemas/common-schemas.ts +0 -393
- package/src/scripts/test-all-prompts.ts +0 -184
- package/src/server.ts +0 -277
- package/src/tools/__tests__/dex-tools.test.ts +0 -562
- package/src/tools/__tests__/liquidity-positions.test.ts +0 -673
- package/src/tools/balance/index.ts +0 -174
- package/src/tools/creation/index.ts +0 -182
- package/src/tools/dex/index.ts +0 -226
- package/src/tools/dex/liquidity-positions.ts +0 -547
- package/src/tools/index.ts +0 -86
- package/src/tools/pools/fetchAllPools.ts +0 -47
- package/src/tools/pools/fetchAllPriceHistory.ts +0 -119
- package/src/tools/pools/fetchPoolDetails.ts +0 -27
- package/src/tools/pools/fetchPoolDetailsForCalculation.ts +0 -22
- package/src/tools/pools/fetchPools.ts +0 -47
- package/src/tools/pools/fetchPriceHistory.ts +0 -124
- package/src/tools/pools/fetchTokenDetails.ts +0 -77
- package/src/tools/pools/index.ts +0 -284
- package/src/tools/social/index.ts +0 -64
- package/src/tools/trading/index.ts +0 -605
- package/src/tools/transfers/index.ts +0 -75
- package/src/tools/utils/clearCache.ts +0 -36
- package/src/tools/utils/createWallet.ts +0 -19
- package/src/tools/utils/explainSdkUsage.ts +0 -1446
- package/src/tools/utils/getAddress.ts +0 -12
- package/src/tools/utils/getCacheInfo.ts +0 -14
- package/src/tools/utils/getConfig.ts +0 -11
- package/src/tools/utils/getEthereumAddress.ts +0 -12
- package/src/tools/utils/getUrlByTokenName.ts +0 -12
- package/src/tools/utils/getVersion.ts +0 -25
- package/src/tools/utils/getWallet.ts +0 -25
- package/src/tools/utils/hasWallet.ts +0 -15
- package/src/tools/utils/index.ts +0 -33
- package/src/tools/utils/isTokenGraduated.ts +0 -16
- package/src/tools/utils/setWallet.ts +0 -41
- package/src/types/mcp.ts +0 -72
- package/src/utils/__tests__/validation.test.ts +0 -147
- package/src/utils/constraints.ts +0 -155
- package/src/utils/default-values.ts +0 -208
- package/src/utils/error-handler.ts +0 -69
- package/src/utils/error-templates.ts +0 -273
- package/src/utils/response-formatter.ts +0 -51
- package/src/utils/tool-factory.ts +0 -257
- package/src/utils/tool-registry.ts +0 -296
- package/src/utils/validation.ts +0 -371
- package/tests/wallet-management-integration.test.ts +0 -284
- package/tsconfig.json +0 -23
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration Tests for Pool Tools
|
|
3
|
-
*
|
|
4
|
-
* These tests use real SDK instances and make actual API calls.
|
|
5
|
-
* Requires valid PRIVATE_KEY environment variable.
|
|
6
|
-
*
|
|
7
|
-
* Run with: npm run test:integration
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { AgentConfig } from '@gala-chain/launchpad-sdk';
|
|
11
|
-
import { fetchPoolsTool, fetchPoolDetailsTool } from '../../tools/pools/index.js';
|
|
12
|
-
|
|
13
|
-
describe('Pool Tools Integration', () => {
|
|
14
|
-
let sdk: any;
|
|
15
|
-
|
|
16
|
-
beforeAll(async () => {
|
|
17
|
-
// Skip tests if no private key available
|
|
18
|
-
if (!process.env.PRIVATE_KEY) {
|
|
19
|
-
console.warn('⚠️ Skipping integration tests: PRIVATE_KEY environment variable not set');
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Initialize SDK with AgentConfig
|
|
24
|
-
const { sdk: initializedSdk } = await AgentConfig.quickSetup({
|
|
25
|
-
environment: (process.env.ENVIRONMENT as any) || 'development',
|
|
26
|
-
privateKey: process.env.PRIVATE_KEY,
|
|
27
|
-
timeout: 30000,
|
|
28
|
-
debug: false,
|
|
29
|
-
autoValidate: false,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
sdk = initializedSdk;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
afterAll(() => {
|
|
36
|
-
if (sdk) {
|
|
37
|
-
sdk.cleanup();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe('fetchPoolsTool', () => {
|
|
42
|
-
it('should fetch recent pools successfully', async () => {
|
|
43
|
-
if (!sdk) {
|
|
44
|
-
return; // Skip if SDK not initialized
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const result = await fetchPoolsTool.handler(sdk, {
|
|
48
|
-
type: 'recent',
|
|
49
|
-
limit: 5,
|
|
50
|
-
page: 1,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
expect(result).toBeDefined();
|
|
54
|
-
expect(result.content).toBeDefined();
|
|
55
|
-
expect(Array.isArray(result.content)).toBe(true);
|
|
56
|
-
expect(result.content.length).toBeGreaterThan(0);
|
|
57
|
-
|
|
58
|
-
const response = JSON.parse(result.content[0].text!);
|
|
59
|
-
expect(response).toHaveProperty('pools');
|
|
60
|
-
expect(Array.isArray(response.pools)).toBe(true);
|
|
61
|
-
expect(response.pools.length).toBeLessThanOrEqual(5);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should fetch popular pools successfully', async () => {
|
|
65
|
-
if (!sdk) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const result = await fetchPoolsTool.handler(sdk, {
|
|
70
|
-
type: 'popular',
|
|
71
|
-
limit: 3,
|
|
72
|
-
page: 1,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
expect(result).toBeDefined();
|
|
76
|
-
const response = JSON.parse(result.content[0].text!);
|
|
77
|
-
expect(response).toHaveProperty('pools');
|
|
78
|
-
expect(response.pools.length).toBeLessThanOrEqual(3);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should handle pagination correctly', async () => {
|
|
82
|
-
if (!sdk) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const page1 = await fetchPoolsTool.handler(sdk, {
|
|
87
|
-
type: 'recent',
|
|
88
|
-
limit: 2,
|
|
89
|
-
page: 1,
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
const page2 = await fetchPoolsTool.handler(sdk, {
|
|
93
|
-
type: 'recent',
|
|
94
|
-
limit: 2,
|
|
95
|
-
page: 2,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const response1 = JSON.parse(page1.content[0].text!);
|
|
99
|
-
const response2 = JSON.parse(page2.content[0].text!);
|
|
100
|
-
|
|
101
|
-
expect(response1.page).toBe(1);
|
|
102
|
-
expect(response2.page).toBe(2);
|
|
103
|
-
|
|
104
|
-
// Different pools on different pages
|
|
105
|
-
if (response1.pools.length > 0 && response2.pools.length > 0) {
|
|
106
|
-
expect(response1.pools[0].name).not.toBe(response2.pools[0].name);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('fetchPoolDetailsTool', () => {
|
|
112
|
-
it('should fetch pool details for a known token', async () => {
|
|
113
|
-
if (!sdk) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// First get a pool name from recent pools
|
|
118
|
-
const pools = await fetchPoolsTool.handler(sdk, {
|
|
119
|
-
type: 'recent',
|
|
120
|
-
limit: 1,
|
|
121
|
-
page: 1,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const poolsResponse = JSON.parse(pools.content[0].text!);
|
|
125
|
-
|
|
126
|
-
if (poolsResponse.pools.length === 0) {
|
|
127
|
-
console.warn('⚠️ No pools available for testing');
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const tokenName = poolsResponse.pools[0].name;
|
|
132
|
-
|
|
133
|
-
// Fetch details for that token
|
|
134
|
-
const result = await fetchPoolDetailsTool.handler(sdk, {
|
|
135
|
-
tokenName,
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
expect(result).toBeDefined();
|
|
139
|
-
const response = JSON.parse(result.content[0].text!);
|
|
140
|
-
|
|
141
|
-
expect(response).toHaveProperty('name', tokenName);
|
|
142
|
-
expect(response).toHaveProperty('symbol');
|
|
143
|
-
expect(response).toHaveProperty('saleStatus');
|
|
144
|
-
expect(response).toHaveProperty('currentSupply');
|
|
145
|
-
expect(response).toHaveProperty('maxSupply');
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('should handle non-existent token gracefully', async () => {
|
|
149
|
-
if (!sdk) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const result = await fetchPoolDetailsTool.handler(sdk, {
|
|
154
|
-
tokenName: 'nonexistenttoken123456',
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// Should return error response
|
|
158
|
-
expect(result).toBeDefined();
|
|
159
|
-
expect(result.isError).toBe(true);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('MCP Response Format', () => {
|
|
164
|
-
it('should return valid MCP response structure', async () => {
|
|
165
|
-
if (!sdk) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const result = await fetchPoolsTool.handler(sdk, {
|
|
170
|
-
type: 'recent',
|
|
171
|
-
limit: 1,
|
|
172
|
-
page: 1,
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Validate MCP response structure
|
|
176
|
-
expect(result).toHaveProperty('content');
|
|
177
|
-
expect(Array.isArray(result.content)).toBe(true);
|
|
178
|
-
expect(result.content[0]).toHaveProperty('type', 'text');
|
|
179
|
-
expect(result.content[0]).toHaveProperty('text');
|
|
180
|
-
|
|
181
|
-
// Validate JSON parseable
|
|
182
|
-
expect(() => JSON.parse(result.content[0].text!)).not.toThrow();
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
});
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tool Name Constants
|
|
3
|
-
*
|
|
4
|
-
* Centralized constants for all Gala Launchpad MCP tool names.
|
|
5
|
-
* Use these constants instead of hardcoded strings to prevent typos
|
|
6
|
-
* and enable IDE autocomplete.
|
|
7
|
-
*
|
|
8
|
-
* Total: 48 tools across 7 categories
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Pool Management & Pricing Tools (13 tools)
|
|
13
|
-
*/
|
|
14
|
-
export const POOL_TOOLS = {
|
|
15
|
-
FETCH_POOLS: 'gala_launchpad_fetch_pools',
|
|
16
|
-
FETCH_ALL_POOLS: 'gala_launchpad_fetch_all_pools',
|
|
17
|
-
FETCH_POOL_DETAILS: 'gala_launchpad_fetch_pool_details',
|
|
18
|
-
FETCH_POOL_DETAILS_FOR_CALCULATION: 'gala_launchpad_fetch_pool_details_for_calculation',
|
|
19
|
-
FETCH_TOKEN_DISTRIBUTION: 'gala_launchpad_fetch_token_distribution',
|
|
20
|
-
FETCH_TOKEN_BADGES: 'gala_launchpad_fetch_token_badges',
|
|
21
|
-
FETCH_VOLUME_DATA: 'gala_launchpad_fetch_volume_data',
|
|
22
|
-
FETCH_GALA_SPOT_PRICE: 'gala_launchpad_fetch_gala_spot_price',
|
|
23
|
-
FETCH_TOKEN_SPOT_PRICE: 'gala_launchpad_fetch_token_spot_price',
|
|
24
|
-
FETCH_LAUNCHPAD_TOKEN_SPOT_PRICE: 'gala_launchpad_fetch_launchpad_token_spot_price',
|
|
25
|
-
CHECK_TOKEN_NAME: 'gala_launchpad_check_token_name',
|
|
26
|
-
CHECK_TOKEN_SYMBOL: 'gala_launchpad_check_token_symbol',
|
|
27
|
-
IS_TOKEN_GRADUATED: 'gala_launchpad_is_token_graduated',
|
|
28
|
-
} as const;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Trading Operations Tools (9 tools)
|
|
32
|
-
*/
|
|
33
|
-
export const TRADING_TOOLS = {
|
|
34
|
-
CALCULATE_BUY_AMOUNT: 'gala_launchpad_calculate_buy_amount',
|
|
35
|
-
CALCULATE_BUY_AMOUNT_LOCAL: 'gala_launchpad_calculate_buy_amount_local',
|
|
36
|
-
CALCULATE_BUY_AMOUNT_EXTERNAL: 'gala_launchpad_calculate_buy_amount_external',
|
|
37
|
-
CALCULATE_SELL_AMOUNT: 'gala_launchpad_calculate_sell_amount',
|
|
38
|
-
CALCULATE_SELL_AMOUNT_LOCAL: 'gala_launchpad_calculate_sell_amount_local',
|
|
39
|
-
CALCULATE_SELL_AMOUNT_EXTERNAL: 'gala_launchpad_calculate_sell_amount_external',
|
|
40
|
-
CALCULATE_BUY_AMOUNT_FOR_GRADUATION: 'gala_launchpad_calculate_buy_amount_for_graduation',
|
|
41
|
-
BUY_TOKENS: 'gala_launchpad_buy_tokens',
|
|
42
|
-
SELL_TOKENS: 'gala_launchpad_sell_tokens',
|
|
43
|
-
GRADUATE_TOKEN: 'gala_launchpad_graduate_token',
|
|
44
|
-
FETCH_TRADES: 'gala_launchpad_fetch_trades',
|
|
45
|
-
GET_BUNDLER_TRANSACTION_RESULT: 'gala_launchpad_get_bundler_transaction_result',
|
|
46
|
-
} as const;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Balance & Portfolio Tools (6 tools)
|
|
50
|
-
*/
|
|
51
|
-
export const BALANCE_TOOLS = {
|
|
52
|
-
FETCH_GALA_BALANCE: 'gala_launchpad_fetch_gala_balance',
|
|
53
|
-
FETCH_TOKEN_BALANCE: 'gala_launchpad_fetch_token_balance',
|
|
54
|
-
FETCH_TOKENS_HELD: 'gala_launchpad_fetch_tokens_held',
|
|
55
|
-
FETCH_TOKENS_CREATED: 'gala_launchpad_fetch_tokens_created',
|
|
56
|
-
FETCH_PROFILE: 'gala_launchpad_fetch_profile',
|
|
57
|
-
UPDATE_PROFILE: 'gala_launchpad_update_profile',
|
|
58
|
-
} as const;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Token Creation Tools (4 tools)
|
|
62
|
-
*/
|
|
63
|
-
export const CREATION_TOOLS = {
|
|
64
|
-
LAUNCH_TOKEN: 'gala_launchpad_launch_token',
|
|
65
|
-
UPLOAD_TOKEN_IMAGE: 'gala_launchpad_upload_token_image',
|
|
66
|
-
UPLOAD_PROFILE_IMAGE: 'gala_launchpad_upload_profile_image',
|
|
67
|
-
FETCH_LAUNCH_TOKEN_FEE: 'gala_launchpad_fetch_launch_token_fee',
|
|
68
|
-
CALCULATE_INITIAL_BUY: 'gala_launchpad_calculate_initial_buy',
|
|
69
|
-
} as const;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Social & Comments Tools (2 tools)
|
|
73
|
-
*/
|
|
74
|
-
export const SOCIAL_TOOLS = {
|
|
75
|
-
POST_COMMENT: 'gala_launchpad_post_comment',
|
|
76
|
-
FETCH_COMMENTS: 'gala_launchpad_fetch_comments',
|
|
77
|
-
} as const;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Token Transfer Tools (2 tools)
|
|
81
|
-
*/
|
|
82
|
-
export const TRANSFER_TOOLS = {
|
|
83
|
-
TRANSFER_GALA: 'gala_launchpad_transfer_gala',
|
|
84
|
-
TRANSFER_TOKEN: 'gala_launchpad_transfer_token',
|
|
85
|
-
} as const;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Utility Tools (6 tools)
|
|
89
|
-
*/
|
|
90
|
-
export const UTILITY_TOOLS = {
|
|
91
|
-
CREATE_WALLET: 'gala_launchpad_create_wallet',
|
|
92
|
-
GET_ADDRESS: 'gala_launchpad_get_address',
|
|
93
|
-
GET_ETHEREUM_ADDRESS: 'gala_launchpad_get_ethereum_address',
|
|
94
|
-
GET_CONFIG: 'gala_launchpad_get_config',
|
|
95
|
-
GET_URL_BY_TOKEN_NAME: 'gala_launchpad_get_url_by_token_name',
|
|
96
|
-
RESOLVE_TOKEN_CLASS_KEY: 'gala_launchpad_resolve_token_class_key',
|
|
97
|
-
RESOLVE_VAULT_ADDRESS: 'gala_launchpad_resolve_vault_address',
|
|
98
|
-
EXPLAIN_SDK_USAGE: 'gala_launchpad_explain_sdk_usage',
|
|
99
|
-
} as const;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* All MCP Tools - Flat structure for easy access
|
|
103
|
-
*
|
|
104
|
-
* Use specific category constants above for better organization,
|
|
105
|
-
* or use this flat object for backwards compatibility.
|
|
106
|
-
*/
|
|
107
|
-
export const MCP_TOOLS = {
|
|
108
|
-
// Pool Management & Pricing
|
|
109
|
-
...POOL_TOOLS,
|
|
110
|
-
// Trading Operations
|
|
111
|
-
...TRADING_TOOLS,
|
|
112
|
-
// Balance & Portfolio
|
|
113
|
-
...BALANCE_TOOLS,
|
|
114
|
-
// Token Creation
|
|
115
|
-
...CREATION_TOOLS,
|
|
116
|
-
// Social & Comments
|
|
117
|
-
...SOCIAL_TOOLS,
|
|
118
|
-
// Token Transfers
|
|
119
|
-
...TRANSFER_TOOLS,
|
|
120
|
-
// Utilities
|
|
121
|
-
...UTILITY_TOOLS,
|
|
122
|
-
} as const;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Type helper for tool names
|
|
126
|
-
*/
|
|
127
|
-
export type MCPToolName = (typeof MCP_TOOLS)[keyof typeof MCP_TOOLS];
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Get all tool names as an array
|
|
131
|
-
*/
|
|
132
|
-
export function getAllToolNames(): string[] {
|
|
133
|
-
return Object.values(MCP_TOOLS);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Check if a string is a valid MCP tool name
|
|
138
|
-
*/
|
|
139
|
-
export function isValidToolName(name: string): name is MCPToolName {
|
|
140
|
-
return getAllToolNames().includes(name);
|
|
141
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Gala Launchpad MCP Server Entry Point
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { LaunchpadMCPServer } from './server.js';
|
|
7
|
-
|
|
8
|
-
async function main() {
|
|
9
|
-
const server = new LaunchpadMCPServer();
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
await server.start();
|
|
13
|
-
} catch (error) {
|
|
14
|
-
console.error('[MCP Server] Fatal error:', error);
|
|
15
|
-
process.exit(1);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
main();
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt Structure Tests
|
|
3
|
-
*
|
|
4
|
-
* Validates that all prompts conform to MCP protocol specification
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { prompts } from '../index';
|
|
8
|
-
|
|
9
|
-
describe('Prompt Structure', () => {
|
|
10
|
-
// Helper to generate valid args for each prompt type
|
|
11
|
-
function getValidArgsForPrompt(promptName: string): Record<string, string> {
|
|
12
|
-
if (promptName.includes('analyze-token') || promptName.includes('pool-details')) {
|
|
13
|
-
return { tokenName: 'anime' };
|
|
14
|
-
}
|
|
15
|
-
if (promptName.includes('buy-tokens')) {
|
|
16
|
-
return { tokenName: 'anime', galaAmount: '100' };
|
|
17
|
-
}
|
|
18
|
-
if (promptName.includes('sell-tokens')) {
|
|
19
|
-
return { tokenName: 'anime', tokenAmount: '1000' };
|
|
20
|
-
}
|
|
21
|
-
if (promptName.includes('graduate-token')) {
|
|
22
|
-
return { tokenName: 'anime' };
|
|
23
|
-
}
|
|
24
|
-
if (promptName.includes('create-token')) {
|
|
25
|
-
return {
|
|
26
|
-
tokenName: 'mytoken',
|
|
27
|
-
tokenSymbol: 'MTK',
|
|
28
|
-
description: 'Test token description',
|
|
29
|
-
websiteUrl: 'https://example.com',
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
if (promptName.includes('discover-tokens')) {
|
|
33
|
-
return { type: 'recent', limit: '10' };
|
|
34
|
-
}
|
|
35
|
-
if (promptName.includes('compare-tokens')) {
|
|
36
|
-
return { token1: 'anime', token2: 'test' };
|
|
37
|
-
}
|
|
38
|
-
if (promptName.includes('graduation-status') || promptName.includes('spot-prices')) {
|
|
39
|
-
return { tokens: 'anime,test,dragon' };
|
|
40
|
-
}
|
|
41
|
-
if (promptName.includes('dex-swap')) {
|
|
42
|
-
return { fromToken: 'GALA', toToken: 'GUSDC', amount: '100' };
|
|
43
|
-
}
|
|
44
|
-
if (promptName.includes('add-liquidity')) {
|
|
45
|
-
return { token0: 'GALA', token1: 'GUSDC', amount0: '1000', amount1: '1000' };
|
|
46
|
-
}
|
|
47
|
-
if (promptName.includes('remove-liquidity')) {
|
|
48
|
-
return { positionId: 'position-123', amount0: '500', amount1: '500' };
|
|
49
|
-
}
|
|
50
|
-
if (promptName.includes('collect-fees')) {
|
|
51
|
-
return { positionId: 'position-123' };
|
|
52
|
-
}
|
|
53
|
-
return {}; // For prompts with no required args (portfolio, balance, my-positions, version, etc.)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
describe('MCP Protocol Compliance', () => {
|
|
57
|
-
it.each(prompts)('$name should have required fields', (prompt) => {
|
|
58
|
-
expect(prompt).toHaveProperty('name');
|
|
59
|
-
expect(prompt).toHaveProperty('description');
|
|
60
|
-
expect(prompt).toHaveProperty('handler');
|
|
61
|
-
expect(typeof prompt.name).toBe('string');
|
|
62
|
-
expect(typeof prompt.description).toBe('string');
|
|
63
|
-
expect(typeof prompt.handler).toBe('function');
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it.each(prompts)('$name should have valid argument structure', (prompt) => {
|
|
67
|
-
if (prompt.arguments) {
|
|
68
|
-
expect(Array.isArray(prompt.arguments)).toBe(true);
|
|
69
|
-
prompt.arguments.forEach((arg) => {
|
|
70
|
-
expect(arg).toHaveProperty('name');
|
|
71
|
-
expect(arg).toHaveProperty('description');
|
|
72
|
-
expect(arg).toHaveProperty('required');
|
|
73
|
-
expect(typeof arg.name).toBe('string');
|
|
74
|
-
expect(typeof arg.description).toBe('string');
|
|
75
|
-
expect(typeof arg.required).toBe('boolean');
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it.each(prompts)('$name handler should return PromptMessage array', (prompt) => {
|
|
81
|
-
const args = getValidArgsForPrompt(prompt.name);
|
|
82
|
-
const messages = prompt.handler(args);
|
|
83
|
-
expect(Array.isArray(messages)).toBe(true);
|
|
84
|
-
expect(messages.length).toBeGreaterThan(0);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it.each(prompts)('$name messages should have valid structure', (prompt) => {
|
|
88
|
-
const args = getValidArgsForPrompt(prompt.name);
|
|
89
|
-
const messages = prompt.handler(args);
|
|
90
|
-
messages.forEach((msg) => {
|
|
91
|
-
expect(msg).toHaveProperty('role');
|
|
92
|
-
expect(msg).toHaveProperty('content');
|
|
93
|
-
expect(['user', 'assistant']).toContain(msg.role);
|
|
94
|
-
expect(msg.content).toHaveProperty('type');
|
|
95
|
-
expect(['text', 'image', 'resource']).toContain(msg.content.type);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('Handler Execution', () => {
|
|
101
|
-
it('analyze-token handler should accept tokenName', () => {
|
|
102
|
-
const prompt = prompts.find((p) => p.name === 'galachain-launchpad:analyze-token');
|
|
103
|
-
expect(() => prompt?.handler({ tokenName: 'anime' })).not.toThrow();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('buy-tokens handler should accept required args', () => {
|
|
107
|
-
const prompt = prompts.find((p) => p.name === 'galachain-launchpad:buy-tokens');
|
|
108
|
-
expect(() => prompt?.handler({ tokenName: 'anime', galaAmount: '100' })).not.toThrow();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('graduate-token handler should accept optional slippage', () => {
|
|
112
|
-
const prompt = prompts.find((p) => p.name === 'galachain-launchpad:graduate-token');
|
|
113
|
-
expect(() => prompt?.handler({ tokenName: 'anime', slippage: '2' })).not.toThrow();
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
describe('Message Content', () => {
|
|
118
|
-
it.each(prompts)('$name should generate non-empty text content', (prompt) => {
|
|
119
|
-
const args = getValidArgsForPrompt(prompt.name);
|
|
120
|
-
const messages = prompt.handler(args);
|
|
121
|
-
messages.forEach((msg) => {
|
|
122
|
-
if (msg.content.type === 'text') {
|
|
123
|
-
expect(msg.content.text).toBeDefined();
|
|
124
|
-
expect(msg.content.text!.length).toBeGreaterThan(10);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it.each(prompts)('$name should reference MCP tools in instructions', (prompt) => {
|
|
130
|
-
const args = getValidArgsForPrompt(prompt.name);
|
|
131
|
-
const messages = prompt.handler(args);
|
|
132
|
-
const text = messages[0].content.text || '';
|
|
133
|
-
// Should contain at least one tool reference
|
|
134
|
-
expect(text).toMatch(/gala_launchpad_/);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
});
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompt Registry Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests for prompt registration, lookup, and utility functions
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
prompts,
|
|
9
|
-
getPrompt,
|
|
10
|
-
getPromptNames,
|
|
11
|
-
hasPrompt,
|
|
12
|
-
getPromptsByCategory,
|
|
13
|
-
getPromptCount,
|
|
14
|
-
} from '../index';
|
|
15
|
-
|
|
16
|
-
describe('Prompt Registry', () => {
|
|
17
|
-
describe('prompts array', () => {
|
|
18
|
-
it('should contain exactly 23 prompts', () => {
|
|
19
|
-
expect(prompts).toHaveLength(23);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('should have all unique prompt names', () => {
|
|
23
|
-
const names = prompts.map((p) => p.name);
|
|
24
|
-
const uniqueNames = new Set(names);
|
|
25
|
-
expect(uniqueNames.size).toBe(names.length);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should have all prompts with galachain-launchpad prefix', () => {
|
|
29
|
-
prompts.forEach((prompt) => {
|
|
30
|
-
expect(prompt.name).toMatch(/^galachain-launchpad:/);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('getPrompt()', () => {
|
|
36
|
-
it('should return prompt for valid name', () => {
|
|
37
|
-
const prompt = getPrompt('galachain-launchpad:analyze-token');
|
|
38
|
-
expect(prompt).toBeDefined();
|
|
39
|
-
expect(prompt?.name).toBe('galachain-launchpad:analyze-token');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should return undefined for invalid name', () => {
|
|
43
|
-
const prompt = getPrompt('non-existent-prompt');
|
|
44
|
-
expect(prompt).toBeUndefined();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should find all 23 prompts by name', () => {
|
|
48
|
-
const names = [
|
|
49
|
-
'galachain-launchpad:analyze-token',
|
|
50
|
-
'galachain-launchpad:buy-tokens',
|
|
51
|
-
'galachain-launchpad:sell-tokens',
|
|
52
|
-
'galachain-launchpad:graduate-token',
|
|
53
|
-
'galachain-launchpad:portfolio',
|
|
54
|
-
'galachain-launchpad:tokens-held',
|
|
55
|
-
'galachain-launchpad:tokens-created',
|
|
56
|
-
'galachain-launchpad:balance',
|
|
57
|
-
'galachain-launchpad:profile',
|
|
58
|
-
'galachain-launchpad:compare-tokens',
|
|
59
|
-
'galachain-launchpad:graduation-status',
|
|
60
|
-
'galachain-launchpad:spot-prices',
|
|
61
|
-
'galachain-launchpad:pool-details',
|
|
62
|
-
'galachain-launchpad:trade-history',
|
|
63
|
-
'galachain-launchpad:fetch-all-pools',
|
|
64
|
-
'galachain-launchpad:create-token',
|
|
65
|
-
'galachain-launchpad:discover-tokens',
|
|
66
|
-
'galachain-launchpad:dex-swap',
|
|
67
|
-
'galachain-launchpad:my-positions',
|
|
68
|
-
'galachain-launchpad:add-liquidity',
|
|
69
|
-
'galachain-launchpad:remove-liquidity',
|
|
70
|
-
'galachain-launchpad:collect-fees',
|
|
71
|
-
'galachain-launchpad:version',
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
names.forEach((name) => {
|
|
75
|
-
const prompt = getPrompt(name);
|
|
76
|
-
expect(prompt).toBeDefined();
|
|
77
|
-
expect(prompt?.name).toBe(name);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should use O(1) Map lookup (performance test)', () => {
|
|
82
|
-
const iterations = 10000;
|
|
83
|
-
const start = Date.now();
|
|
84
|
-
|
|
85
|
-
for (let i = 0; i < iterations; i++) {
|
|
86
|
-
getPrompt('galachain-launchpad:analyze-token');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const duration = Date.now() - start;
|
|
90
|
-
// Should complete 10k lookups in under 100ms (Map is O(1))
|
|
91
|
-
expect(duration).toBeLessThan(100);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('getPromptNames()', () => {
|
|
96
|
-
it('should return array of all prompt names', () => {
|
|
97
|
-
const names = getPromptNames();
|
|
98
|
-
expect(names).toHaveLength(23);
|
|
99
|
-
expect(names).toContain('galachain-launchpad:analyze-token');
|
|
100
|
-
expect(names).toContain('galachain-launchpad:buy-tokens');
|
|
101
|
-
expect(names).toContain('galachain-launchpad:create-token');
|
|
102
|
-
expect(names).toContain('galachain-launchpad:discover-tokens');
|
|
103
|
-
expect(names).toContain('galachain-launchpad:my-positions');
|
|
104
|
-
expect(names).toContain('galachain-launchpad:add-liquidity');
|
|
105
|
-
expect(names).toContain('galachain-launchpad:remove-liquidity');
|
|
106
|
-
expect(names).toContain('galachain-launchpad:collect-fees');
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('should return names in consistent order', () => {
|
|
110
|
-
const names1 = getPromptNames();
|
|
111
|
-
const names2 = getPromptNames();
|
|
112
|
-
expect(names1).toEqual(names2);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe('hasPrompt()', () => {
|
|
117
|
-
it('should return true for existing prompts', () => {
|
|
118
|
-
expect(hasPrompt('galachain-launchpad:analyze-token')).toBe(true);
|
|
119
|
-
expect(hasPrompt('galachain-launchpad:buy-tokens')).toBe(true);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should return false for non-existent prompts', () => {
|
|
123
|
-
expect(hasPrompt('invalid-prompt')).toBe(false);
|
|
124
|
-
expect(hasPrompt('')).toBe(false);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
describe('getPromptsByCategory()', () => {
|
|
129
|
-
it('should return 4 trading prompts', () => {
|
|
130
|
-
const trading = getPromptsByCategory('trading');
|
|
131
|
-
expect(trading).toHaveLength(4);
|
|
132
|
-
expect(trading[0].name).toContain('analyze-token');
|
|
133
|
-
expect(trading[1].name).toContain('buy-tokens');
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('should return 5 portfolio prompts', () => {
|
|
137
|
-
const portfolio = getPromptsByCategory('portfolio');
|
|
138
|
-
expect(portfolio).toHaveLength(5);
|
|
139
|
-
expect(portfolio[0].name).toContain('portfolio');
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('should return 6 analysis prompts', () => {
|
|
143
|
-
const analysis = getPromptsByCategory('analysis');
|
|
144
|
-
expect(analysis).toHaveLength(6);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it('should return 1 creation prompt', () => {
|
|
148
|
-
const creation = getPromptsByCategory('creation');
|
|
149
|
-
expect(creation).toHaveLength(1);
|
|
150
|
-
expect(creation[0].name).toContain('create-token');
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it('should return 1 discovery prompt', () => {
|
|
154
|
-
const discovery = getPromptsByCategory('discovery');
|
|
155
|
-
expect(discovery).toHaveLength(1);
|
|
156
|
-
expect(discovery[0].name).toContain('discover-tokens');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should return 1 dex trading prompt', () => {
|
|
160
|
-
const dex = getPromptsByCategory('dex');
|
|
161
|
-
expect(dex).toHaveLength(1);
|
|
162
|
-
expect(dex[0].name).toContain('dex-swap');
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('should return 4 liquidity position prompts', () => {
|
|
166
|
-
const liquidity = getPromptsByCategory('liquidity');
|
|
167
|
-
expect(liquidity).toHaveLength(4);
|
|
168
|
-
expect(liquidity[0].name).toContain('my-positions');
|
|
169
|
-
expect(liquidity[1].name).toContain('add-liquidity');
|
|
170
|
-
expect(liquidity[2].name).toContain('remove-liquidity');
|
|
171
|
-
expect(liquidity[3].name).toContain('collect-fees');
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it('should return 1 utility prompt', () => {
|
|
175
|
-
const utility = getPromptsByCategory('utility');
|
|
176
|
-
expect(utility).toHaveLength(1);
|
|
177
|
-
expect(utility[0].name).toContain('version');
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should return empty array for invalid category', () => {
|
|
181
|
-
const result = getPromptsByCategory('invalid' as any);
|
|
182
|
-
expect(result).toEqual([]);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
describe('getPromptCount()', () => {
|
|
187
|
-
it('should return 23', () => {
|
|
188
|
-
expect(getPromptCount()).toBe(23);
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
});
|