@manifest-network/manifest-mcp-browser 0.1.7 → 0.1.8
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/README.md +5 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -10
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -7
- package/dist/index.js.map +1 -1
- package/dist/queries/index.d.ts +1 -0
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +1 -0
- package/dist/queries/index.js.map +1 -1
- package/dist/transactions/bank.d.ts.map +1 -1
- package/dist/transactions/bank.js +7 -5
- package/dist/transactions/bank.js.map +1 -1
- package/dist/transactions/gov.d.ts.map +1 -1
- package/dist/transactions/gov.js +7 -5
- package/dist/transactions/gov.js.map +1 -1
- package/dist/transactions/index.d.ts +1 -0
- package/dist/transactions/index.d.ts.map +1 -1
- package/dist/transactions/index.js +1 -0
- package/dist/transactions/index.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +5 -2
- package/.github/workflows/ci.yml +0 -37
- package/.github/workflows/publish.yml +0 -53
- package/CLAUDE.md +0 -113
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -251
- package/dist/config.test.js.map +0 -1
- package/dist/modules.test.d.ts +0 -2
- package/dist/modules.test.d.ts.map +0 -1
- package/dist/modules.test.js +0 -161
- package/dist/modules.test.js.map +0 -1
- package/dist/queries/utils.test.d.ts +0 -2
- package/dist/queries/utils.test.d.ts.map +0 -1
- package/dist/queries/utils.test.js +0 -117
- package/dist/queries/utils.test.js.map +0 -1
- package/dist/transactions/utils.test.d.ts +0 -2
- package/dist/transactions/utils.test.d.ts.map +0 -1
- package/dist/transactions/utils.test.js +0 -567
- package/dist/transactions/utils.test.js.map +0 -1
- package/src/client.ts +0 -288
- package/src/config.test.ts +0 -299
- package/src/config.ts +0 -174
- package/src/cosmos.ts +0 -106
- package/src/index.ts +0 -478
- package/src/modules.test.ts +0 -191
- package/src/modules.ts +0 -470
- package/src/queries/auth.ts +0 -97
- package/src/queries/bank.ts +0 -99
- package/src/queries/billing.ts +0 -124
- package/src/queries/distribution.ts +0 -114
- package/src/queries/gov.ts +0 -104
- package/src/queries/group.ts +0 -146
- package/src/queries/index.ts +0 -17
- package/src/queries/sku.ts +0 -85
- package/src/queries/staking.ts +0 -154
- package/src/queries/utils.test.ts +0 -156
- package/src/queries/utils.ts +0 -121
- package/src/transactions/bank.ts +0 -86
- package/src/transactions/billing.ts +0 -286
- package/src/transactions/distribution.ts +0 -76
- package/src/transactions/gov.ts +0 -164
- package/src/transactions/group.ts +0 -458
- package/src/transactions/index.ts +0 -8
- package/src/transactions/manifest.ts +0 -67
- package/src/transactions/sku.ts +0 -232
- package/src/transactions/staking.ts +0 -85
- package/src/transactions/utils.test.ts +0 -626
- package/src/transactions/utils.ts +0 -417
- package/src/types.ts +0 -548
- package/src/wallet/index.ts +0 -2
- package/src/wallet/mnemonic.ts +0 -146
- package/tsconfig.json +0 -23
package/src/index.ts
DELETED
|
@@ -1,478 +0,0 @@
|
|
|
1
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
-
import {
|
|
3
|
-
ListToolsRequestSchema,
|
|
4
|
-
CallToolRequestSchema,
|
|
5
|
-
Tool,
|
|
6
|
-
} from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
-
import { CosmosClientManager } from './client.js';
|
|
8
|
-
import { cosmosQuery, cosmosTx } from './cosmos.js';
|
|
9
|
-
import { getAvailableModules, getModuleSubcommands } from './modules.js';
|
|
10
|
-
import {
|
|
11
|
-
ManifestMCPConfig,
|
|
12
|
-
WalletProvider,
|
|
13
|
-
AccountInfo,
|
|
14
|
-
ManifestMCPError,
|
|
15
|
-
ManifestMCPErrorCode,
|
|
16
|
-
} from './types.js';
|
|
17
|
-
import { createValidatedConfig } from './config.js';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Sensitive field names that should be redacted from error responses
|
|
21
|
-
*/
|
|
22
|
-
const SENSITIVE_FIELDS = new Set([
|
|
23
|
-
'mnemonic',
|
|
24
|
-
'privatekey',
|
|
25
|
-
'private_key',
|
|
26
|
-
'secret',
|
|
27
|
-
'password',
|
|
28
|
-
'seed',
|
|
29
|
-
'key',
|
|
30
|
-
'token',
|
|
31
|
-
'apikey',
|
|
32
|
-
'api_key',
|
|
33
|
-
]);
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Parse raw args input into string array.
|
|
37
|
-
* Handles both array and space-separated string inputs.
|
|
38
|
-
*/
|
|
39
|
-
function parseArgs(rawArgs: unknown): string[] {
|
|
40
|
-
if (Array.isArray(rawArgs)) {
|
|
41
|
-
return rawArgs.map(String);
|
|
42
|
-
}
|
|
43
|
-
if (typeof rawArgs === 'string' && rawArgs.length > 0) {
|
|
44
|
-
return rawArgs.split(/\s+/);
|
|
45
|
-
}
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Recursively sanitize an object by redacting sensitive fields
|
|
51
|
-
*/
|
|
52
|
-
function sanitizeForLogging(obj: unknown, depth = 0): unknown {
|
|
53
|
-
// Prevent infinite recursion
|
|
54
|
-
if (depth > 10) {
|
|
55
|
-
return '[max depth exceeded]';
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (obj === null || obj === undefined) {
|
|
59
|
-
return obj;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (typeof obj === 'string') {
|
|
63
|
-
// Redact strings that look like mnemonics (12 or 24 words)
|
|
64
|
-
const wordCount = obj.trim().split(/\s+/).length;
|
|
65
|
-
if (wordCount === 12 || wordCount === 24) {
|
|
66
|
-
return '[REDACTED - possible mnemonic]';
|
|
67
|
-
}
|
|
68
|
-
return obj;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (Array.isArray(obj)) {
|
|
72
|
-
return obj.map(item => sanitizeForLogging(item, depth + 1));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (typeof obj === 'object') {
|
|
76
|
-
const sanitized: Record<string, unknown> = {};
|
|
77
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
78
|
-
const lowerKey = key.toLowerCase();
|
|
79
|
-
if (SENSITIVE_FIELDS.has(lowerKey)) {
|
|
80
|
-
sanitized[key] = '[REDACTED]';
|
|
81
|
-
} else {
|
|
82
|
-
sanitized[key] = sanitizeForLogging(value, depth + 1);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return sanitized;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return obj;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Re-export types and utilities
|
|
92
|
-
export * from './types.js';
|
|
93
|
-
export { createConfig, createValidatedConfig, validateConfig } from './config.js';
|
|
94
|
-
export { CosmosClientManager } from './client.js';
|
|
95
|
-
export { cosmosQuery, cosmosTx } from './cosmos.js';
|
|
96
|
-
export { getAvailableModules, getModuleSubcommands, getSubcommandUsage, getSupportedModules, isSubcommandSupported } from './modules.js';
|
|
97
|
-
export { MnemonicWalletProvider } from './wallet/index.js';
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Tool definitions for the MCP server
|
|
101
|
-
*/
|
|
102
|
-
const tools: Tool[] = [
|
|
103
|
-
{
|
|
104
|
-
name: 'get_account_info',
|
|
105
|
-
description: 'Get account address and key name for the configured key',
|
|
106
|
-
inputSchema: {
|
|
107
|
-
type: 'object',
|
|
108
|
-
properties: {},
|
|
109
|
-
required: [],
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
name: 'cosmos_query',
|
|
114
|
-
description:
|
|
115
|
-
'Execute any Cosmos SDK query command. Use list_modules and list_module_subcommands to discover available options.',
|
|
116
|
-
inputSchema: {
|
|
117
|
-
type: 'object',
|
|
118
|
-
properties: {
|
|
119
|
-
module: {
|
|
120
|
-
type: 'string',
|
|
121
|
-
description:
|
|
122
|
-
'The module name (e.g., "bank", "staking", "distribution", "gov", "auth")',
|
|
123
|
-
},
|
|
124
|
-
subcommand: {
|
|
125
|
-
type: 'string',
|
|
126
|
-
description:
|
|
127
|
-
'The subcommand (e.g., "balance", "balances", "delegations", "rewards", "proposals")',
|
|
128
|
-
},
|
|
129
|
-
args: {
|
|
130
|
-
type: 'array',
|
|
131
|
-
items: { type: 'string' },
|
|
132
|
-
description:
|
|
133
|
-
'Additional arguments as an array of strings (e.g., ["<address>", "umfx"] for bank balance). Use array to preserve arguments with spaces.',
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
required: ['module', 'subcommand'],
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
name: 'cosmos_tx',
|
|
141
|
-
description:
|
|
142
|
-
'Execute any Cosmos SDK transaction. Automatically signs with the configured key and estimates gas. Use list_modules and list_module_subcommands to discover available options.',
|
|
143
|
-
inputSchema: {
|
|
144
|
-
type: 'object',
|
|
145
|
-
properties: {
|
|
146
|
-
module: {
|
|
147
|
-
type: 'string',
|
|
148
|
-
description: 'The module name (e.g., "bank", "staking", "gov")',
|
|
149
|
-
},
|
|
150
|
-
subcommand: {
|
|
151
|
-
type: 'string',
|
|
152
|
-
description: 'The subcommand (e.g., "send", "delegate", "unbond", "vote")',
|
|
153
|
-
},
|
|
154
|
-
args: {
|
|
155
|
-
type: 'array',
|
|
156
|
-
items: { type: 'string' },
|
|
157
|
-
description:
|
|
158
|
-
'Arguments to the transaction as an array of strings (e.g., ["<to_address>", "1000umfx"] for bank send). Use array to preserve arguments with spaces.',
|
|
159
|
-
},
|
|
160
|
-
wait_for_confirmation: {
|
|
161
|
-
type: 'boolean',
|
|
162
|
-
description:
|
|
163
|
-
'If true, wait for the transaction to be included in a block before returning. Defaults to false (broadcast only).',
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
required: ['module', 'subcommand', 'args'],
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: 'list_modules',
|
|
171
|
-
description:
|
|
172
|
-
'List all available query and transaction modules supported by the chain',
|
|
173
|
-
inputSchema: {
|
|
174
|
-
type: 'object',
|
|
175
|
-
properties: {},
|
|
176
|
-
required: [],
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
name: 'list_module_subcommands',
|
|
181
|
-
description:
|
|
182
|
-
'List all available subcommands for a specific module (query or tx)',
|
|
183
|
-
inputSchema: {
|
|
184
|
-
type: 'object',
|
|
185
|
-
properties: {
|
|
186
|
-
type: {
|
|
187
|
-
type: 'string',
|
|
188
|
-
enum: ['query', 'tx'],
|
|
189
|
-
description: 'Whether to list query or transaction subcommands',
|
|
190
|
-
},
|
|
191
|
-
module: {
|
|
192
|
-
type: 'string',
|
|
193
|
-
description: 'The module name (e.g., "bank", "staking")',
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
required: ['type', 'module'],
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
];
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Options for creating a ManifestMCPServer
|
|
203
|
-
*/
|
|
204
|
-
export interface ManifestMCPServerOptions {
|
|
205
|
-
config: ManifestMCPConfig;
|
|
206
|
-
walletProvider: WalletProvider;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* ManifestMCPServer class for browser-compatible MCP server
|
|
211
|
-
*/
|
|
212
|
-
export class ManifestMCPServer {
|
|
213
|
-
private server: Server;
|
|
214
|
-
private clientManager: CosmosClientManager;
|
|
215
|
-
private walletProvider: WalletProvider;
|
|
216
|
-
private config: ManifestMCPConfig;
|
|
217
|
-
|
|
218
|
-
constructor(options: ManifestMCPServerOptions) {
|
|
219
|
-
this.config = createValidatedConfig(options.config);
|
|
220
|
-
this.walletProvider = options.walletProvider;
|
|
221
|
-
this.clientManager = CosmosClientManager.getInstance(this.config, this.walletProvider);
|
|
222
|
-
|
|
223
|
-
// Note: Keep version in sync with package.json
|
|
224
|
-
this.server = new Server(
|
|
225
|
-
{
|
|
226
|
-
name: '@manifest-network/manifest-mcp-browser',
|
|
227
|
-
version: '0.1.1',
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
capabilities: {
|
|
231
|
-
tools: {},
|
|
232
|
-
},
|
|
233
|
-
}
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
this.setupHandlers();
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Set up the MCP request handlers
|
|
241
|
-
*/
|
|
242
|
-
private setupHandlers(): void {
|
|
243
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
244
|
-
tools,
|
|
245
|
-
}));
|
|
246
|
-
|
|
247
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
248
|
-
const toolName = request.params.name;
|
|
249
|
-
const toolInput = request.params.arguments || {};
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
return await this.handleToolCall(toolName, toolInput);
|
|
253
|
-
} catch (error) {
|
|
254
|
-
// Build detailed error response with sanitized inputs
|
|
255
|
-
let errorResponse: Record<string, unknown> = {
|
|
256
|
-
error: true,
|
|
257
|
-
tool: toolName,
|
|
258
|
-
input: sanitizeForLogging(toolInput),
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
if (error instanceof ManifestMCPError) {
|
|
262
|
-
errorResponse = {
|
|
263
|
-
...errorResponse,
|
|
264
|
-
code: error.code,
|
|
265
|
-
message: error.message,
|
|
266
|
-
details: sanitizeForLogging(error.details),
|
|
267
|
-
};
|
|
268
|
-
} else {
|
|
269
|
-
errorResponse = {
|
|
270
|
-
...errorResponse,
|
|
271
|
-
message: error instanceof Error ? error.message : String(error),
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return {
|
|
276
|
-
content: [
|
|
277
|
-
{
|
|
278
|
-
type: 'text',
|
|
279
|
-
text: JSON.stringify(errorResponse, null, 2),
|
|
280
|
-
},
|
|
281
|
-
],
|
|
282
|
-
isError: true,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Handle a tool call
|
|
290
|
-
*/
|
|
291
|
-
private async handleToolCall(
|
|
292
|
-
toolName: string,
|
|
293
|
-
toolInput: Record<string, unknown>
|
|
294
|
-
): Promise<{ content: Array<{ type: string; text: string }>; isError?: boolean }> {
|
|
295
|
-
switch (toolName) {
|
|
296
|
-
case 'get_account_info': {
|
|
297
|
-
const address = await this.walletProvider.getAddress();
|
|
298
|
-
const accountInfo: AccountInfo = {
|
|
299
|
-
address,
|
|
300
|
-
};
|
|
301
|
-
return {
|
|
302
|
-
content: [
|
|
303
|
-
{
|
|
304
|
-
type: 'text',
|
|
305
|
-
text: JSON.stringify(accountInfo, null, 2),
|
|
306
|
-
},
|
|
307
|
-
],
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
case 'cosmos_query': {
|
|
312
|
-
const module = toolInput.module as string;
|
|
313
|
-
const subcommand = toolInput.subcommand as string;
|
|
314
|
-
const args = parseArgs(toolInput.args);
|
|
315
|
-
|
|
316
|
-
if (!module || !subcommand) {
|
|
317
|
-
throw new ManifestMCPError(
|
|
318
|
-
ManifestMCPErrorCode.QUERY_FAILED,
|
|
319
|
-
'module and subcommand are required'
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const result = await cosmosQuery(this.clientManager, module, subcommand, args);
|
|
324
|
-
|
|
325
|
-
return {
|
|
326
|
-
content: [
|
|
327
|
-
{
|
|
328
|
-
type: 'text',
|
|
329
|
-
text: JSON.stringify(result, null, 2),
|
|
330
|
-
},
|
|
331
|
-
],
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
case 'cosmos_tx': {
|
|
336
|
-
const module = toolInput.module as string;
|
|
337
|
-
const subcommand = toolInput.subcommand as string;
|
|
338
|
-
const args = parseArgs(toolInput.args);
|
|
339
|
-
const waitForConfirmation = (toolInput.wait_for_confirmation as boolean) || false;
|
|
340
|
-
|
|
341
|
-
if (!module || !subcommand || args.length === 0) {
|
|
342
|
-
throw new ManifestMCPError(
|
|
343
|
-
ManifestMCPErrorCode.TX_FAILED,
|
|
344
|
-
'module, subcommand, and args are required'
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const result = await cosmosTx(
|
|
349
|
-
this.clientManager,
|
|
350
|
-
module,
|
|
351
|
-
subcommand,
|
|
352
|
-
args,
|
|
353
|
-
waitForConfirmation
|
|
354
|
-
);
|
|
355
|
-
|
|
356
|
-
return {
|
|
357
|
-
content: [
|
|
358
|
-
{
|
|
359
|
-
type: 'text',
|
|
360
|
-
text: JSON.stringify(result, null, 2),
|
|
361
|
-
},
|
|
362
|
-
],
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
case 'list_modules': {
|
|
367
|
-
const modules = getAvailableModules();
|
|
368
|
-
return {
|
|
369
|
-
content: [
|
|
370
|
-
{
|
|
371
|
-
type: 'text',
|
|
372
|
-
text: JSON.stringify(modules, null, 2),
|
|
373
|
-
},
|
|
374
|
-
],
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
case 'list_module_subcommands': {
|
|
379
|
-
const type = toolInput.type as string;
|
|
380
|
-
const module = toolInput.module as string;
|
|
381
|
-
|
|
382
|
-
if (!type || !module) {
|
|
383
|
-
throw new ManifestMCPError(
|
|
384
|
-
ManifestMCPErrorCode.QUERY_FAILED,
|
|
385
|
-
'type and module are required'
|
|
386
|
-
);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
if (type !== 'query' && type !== 'tx') {
|
|
390
|
-
throw new ManifestMCPError(
|
|
391
|
-
ManifestMCPErrorCode.QUERY_FAILED,
|
|
392
|
-
'type must be either "query" or "tx"'
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const subcommands = getModuleSubcommands(type as 'query' | 'tx', module);
|
|
397
|
-
return {
|
|
398
|
-
content: [
|
|
399
|
-
{
|
|
400
|
-
type: 'text',
|
|
401
|
-
text: JSON.stringify(
|
|
402
|
-
{
|
|
403
|
-
type,
|
|
404
|
-
module,
|
|
405
|
-
subcommands,
|
|
406
|
-
},
|
|
407
|
-
null,
|
|
408
|
-
2
|
|
409
|
-
),
|
|
410
|
-
},
|
|
411
|
-
],
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
default:
|
|
416
|
-
throw new ManifestMCPError(
|
|
417
|
-
ManifestMCPErrorCode.UNKNOWN_ERROR,
|
|
418
|
-
`Unknown tool: ${toolName}`
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Get the underlying MCP server instance
|
|
425
|
-
*/
|
|
426
|
-
getServer(): Server {
|
|
427
|
-
return this.server;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Get the client manager
|
|
432
|
-
*/
|
|
433
|
-
getClientManager(): CosmosClientManager {
|
|
434
|
-
return this.clientManager;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Disconnect and clean up resources
|
|
439
|
-
*/
|
|
440
|
-
disconnect(): void {
|
|
441
|
-
this.clientManager.disconnect();
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Create a ManifestMCPServer with mnemonic wallet (for testing or non-interactive use)
|
|
447
|
-
*
|
|
448
|
-
* @example
|
|
449
|
-
* ```typescript
|
|
450
|
-
* import { createMnemonicServer } from '@manifest-network/manifest-mcp-browser';
|
|
451
|
-
*
|
|
452
|
-
* const server = await createMnemonicServer({
|
|
453
|
-
* chainId: 'manifest-ledger-testnet',
|
|
454
|
-
* rpcUrl: 'https://nodes.chandrastation.com/rpc/manifest/',
|
|
455
|
-
* gasPrice: '1.0umfx',
|
|
456
|
-
* mnemonic: 'your twelve word mnemonic phrase here...',
|
|
457
|
-
* });
|
|
458
|
-
* ```
|
|
459
|
-
*/
|
|
460
|
-
export async function createMnemonicServer(config: {
|
|
461
|
-
chainId: string;
|
|
462
|
-
rpcUrl: string;
|
|
463
|
-
gasPrice: string;
|
|
464
|
-
gasAdjustment?: number;
|
|
465
|
-
addressPrefix?: string;
|
|
466
|
-
mnemonic: string;
|
|
467
|
-
}): Promise<ManifestMCPServer> {
|
|
468
|
-
const { MnemonicWalletProvider } = await import('./wallet/mnemonic.js');
|
|
469
|
-
|
|
470
|
-
const { mnemonic, ...mcpConfig } = config;
|
|
471
|
-
const walletProvider = new MnemonicWalletProvider(mcpConfig, mnemonic);
|
|
472
|
-
await walletProvider.connect();
|
|
473
|
-
|
|
474
|
-
return new ManifestMCPServer({
|
|
475
|
-
config: mcpConfig,
|
|
476
|
-
walletProvider,
|
|
477
|
-
});
|
|
478
|
-
}
|
package/src/modules.test.ts
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
getAvailableModules,
|
|
4
|
-
getModuleSubcommands,
|
|
5
|
-
isSubcommandSupported,
|
|
6
|
-
getSupportedModules,
|
|
7
|
-
throwUnsupportedSubcommand,
|
|
8
|
-
} from './modules.js';
|
|
9
|
-
import { ManifestMCPError, ManifestMCPErrorCode } from './types.js';
|
|
10
|
-
|
|
11
|
-
describe('getAvailableModules', () => {
|
|
12
|
-
it('should return query and tx modules', () => {
|
|
13
|
-
const modules = getAvailableModules();
|
|
14
|
-
|
|
15
|
-
expect(modules.queryModules).toBeDefined();
|
|
16
|
-
expect(modules.txModules).toBeDefined();
|
|
17
|
-
expect(modules.queryModules.length).toBeGreaterThan(0);
|
|
18
|
-
expect(modules.txModules.length).toBeGreaterThan(0);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should include expected query modules', () => {
|
|
22
|
-
const modules = getAvailableModules();
|
|
23
|
-
const queryNames = modules.queryModules.map(m => m.name);
|
|
24
|
-
|
|
25
|
-
expect(queryNames).toContain('bank');
|
|
26
|
-
expect(queryNames).toContain('staking');
|
|
27
|
-
expect(queryNames).toContain('distribution');
|
|
28
|
-
expect(queryNames).toContain('gov');
|
|
29
|
-
expect(queryNames).toContain('auth');
|
|
30
|
-
expect(queryNames).toContain('billing');
|
|
31
|
-
expect(queryNames).toContain('sku');
|
|
32
|
-
expect(queryNames).toContain('group');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('should include expected tx modules', () => {
|
|
36
|
-
const modules = getAvailableModules();
|
|
37
|
-
const txNames = modules.txModules.map(m => m.name);
|
|
38
|
-
|
|
39
|
-
expect(txNames).toContain('bank');
|
|
40
|
-
expect(txNames).toContain('staking');
|
|
41
|
-
expect(txNames).toContain('distribution');
|
|
42
|
-
expect(txNames).toContain('gov');
|
|
43
|
-
expect(txNames).toContain('billing');
|
|
44
|
-
expect(txNames).toContain('manifest');
|
|
45
|
-
expect(txNames).toContain('sku');
|
|
46
|
-
expect(txNames).toContain('group');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe('getModuleSubcommands', () => {
|
|
51
|
-
it('should return subcommands for valid query module', () => {
|
|
52
|
-
const subcommands = getModuleSubcommands('query', 'bank');
|
|
53
|
-
|
|
54
|
-
expect(subcommands.length).toBeGreaterThan(0);
|
|
55
|
-
expect(subcommands.some(s => s.name === 'balance')).toBe(true);
|
|
56
|
-
expect(subcommands.some(s => s.name === 'balances')).toBe(true);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should return subcommands for valid tx module', () => {
|
|
60
|
-
const subcommands = getModuleSubcommands('tx', 'bank');
|
|
61
|
-
|
|
62
|
-
expect(subcommands.length).toBeGreaterThan(0);
|
|
63
|
-
expect(subcommands.some(s => s.name === 'send')).toBe(true);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should throw ManifestMCPError for unknown module', () => {
|
|
67
|
-
expect(() => getModuleSubcommands('query', 'unknown')).toThrow(ManifestMCPError);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should have UNKNOWN_MODULE error code', () => {
|
|
71
|
-
try {
|
|
72
|
-
getModuleSubcommands('query', 'unknown');
|
|
73
|
-
} catch (error) {
|
|
74
|
-
expect((error as ManifestMCPError).code).toBe(ManifestMCPErrorCode.UNKNOWN_MODULE);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should include aliases in subcommands', () => {
|
|
79
|
-
const bankSubcommands = getModuleSubcommands('query', 'bank');
|
|
80
|
-
expect(bankSubcommands.some(s => s.name === 'total')).toBe(true);
|
|
81
|
-
|
|
82
|
-
const stakingSubcommands = getModuleSubcommands('tx', 'staking');
|
|
83
|
-
expect(stakingSubcommands.some(s => s.name === 'undelegate')).toBe(true);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe('isSubcommandSupported', () => {
|
|
88
|
-
it('should return true for supported query subcommands', () => {
|
|
89
|
-
expect(isSubcommandSupported('query', 'bank', 'balance')).toBe(true);
|
|
90
|
-
expect(isSubcommandSupported('query', 'staking', 'delegation')).toBe(true);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should return true for supported tx subcommands', () => {
|
|
94
|
-
expect(isSubcommandSupported('tx', 'bank', 'send')).toBe(true);
|
|
95
|
-
expect(isSubcommandSupported('tx', 'staking', 'delegate')).toBe(true);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should return false for unsupported subcommands', () => {
|
|
99
|
-
expect(isSubcommandSupported('query', 'bank', 'unknown')).toBe(false);
|
|
100
|
-
expect(isSubcommandSupported('tx', 'bank', 'unknown')).toBe(false);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should return false for unknown modules', () => {
|
|
104
|
-
expect(isSubcommandSupported('query', 'unknown', 'balance')).toBe(false);
|
|
105
|
-
expect(isSubcommandSupported('tx', 'unknown', 'send')).toBe(false);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('should support aliases', () => {
|
|
109
|
-
expect(isSubcommandSupported('query', 'bank', 'total')).toBe(true);
|
|
110
|
-
expect(isSubcommandSupported('tx', 'staking', 'undelegate')).toBe(true);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
describe('getSupportedModules', () => {
|
|
115
|
-
it('should return query and tx module maps', () => {
|
|
116
|
-
const modules = getSupportedModules();
|
|
117
|
-
|
|
118
|
-
expect(modules.query).toBeDefined();
|
|
119
|
-
expect(modules.tx).toBeDefined();
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should include subcommand arrays for each module', () => {
|
|
123
|
-
const modules = getSupportedModules();
|
|
124
|
-
|
|
125
|
-
expect(Array.isArray(modules.query.bank)).toBe(true);
|
|
126
|
-
expect(modules.query.bank).toContain('balance');
|
|
127
|
-
expect(modules.query.bank).toContain('balances');
|
|
128
|
-
|
|
129
|
-
expect(Array.isArray(modules.tx.bank)).toBe(true);
|
|
130
|
-
expect(modules.tx.bank).toContain('send');
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
describe('throwUnsupportedSubcommand', () => {
|
|
135
|
-
it('should throw ManifestMCPError for unsupported query subcommand', () => {
|
|
136
|
-
expect(() => throwUnsupportedSubcommand('query', 'bank', 'unknown')).toThrow(ManifestMCPError);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should throw ManifestMCPError for unsupported tx subcommand', () => {
|
|
140
|
-
expect(() => throwUnsupportedSubcommand('tx', 'bank', 'unknown')).toThrow(ManifestMCPError);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('should use UNSUPPORTED_QUERY error code for queries', () => {
|
|
144
|
-
try {
|
|
145
|
-
throwUnsupportedSubcommand('query', 'bank', 'unknown');
|
|
146
|
-
} catch (error) {
|
|
147
|
-
expect((error as ManifestMCPError).code).toBe(ManifestMCPErrorCode.UNSUPPORTED_QUERY);
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it('should use UNSUPPORTED_TX error code for transactions', () => {
|
|
152
|
-
try {
|
|
153
|
-
throwUnsupportedSubcommand('tx', 'bank', 'unknown');
|
|
154
|
-
} catch (error) {
|
|
155
|
-
expect((error as ManifestMCPError).code).toBe(ManifestMCPErrorCode.UNSUPPORTED_TX);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should include module and subcommand in error message', () => {
|
|
160
|
-
try {
|
|
161
|
-
throwUnsupportedSubcommand('query', 'staking', 'badcmd');
|
|
162
|
-
} catch (error) {
|
|
163
|
-
const message = (error as ManifestMCPError).message;
|
|
164
|
-
expect(message).toContain('staking');
|
|
165
|
-
expect(message).toContain('badcmd');
|
|
166
|
-
expect(message).toContain('query');
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should include availableSubcommands in error details', () => {
|
|
171
|
-
try {
|
|
172
|
-
throwUnsupportedSubcommand('tx', 'bank', 'unknown');
|
|
173
|
-
} catch (error) {
|
|
174
|
-
const details = (error as ManifestMCPError).details;
|
|
175
|
-
expect(details?.availableSubcommands).toBeDefined();
|
|
176
|
-
expect(details?.availableSubcommands).toContain('send');
|
|
177
|
-
expect(details?.availableSubcommands).toContain('multi-send');
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('should include correct subcommands for each module', () => {
|
|
182
|
-
try {
|
|
183
|
-
throwUnsupportedSubcommand('query', 'gov', 'unknown');
|
|
184
|
-
} catch (error) {
|
|
185
|
-
const details = (error as ManifestMCPError).details;
|
|
186
|
-
expect(details?.availableSubcommands).toContain('proposal');
|
|
187
|
-
expect(details?.availableSubcommands).toContain('proposals');
|
|
188
|
-
expect(details?.availableSubcommands).toContain('vote');
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
});
|