Skip to content

Commit 45b1e6b

Browse files
committed
fix: validate network parameter in chain tool handlers
1 parent af4c014 commit 45b1e6b

File tree

2 files changed

+39
-15
lines changed

2 files changed

+39
-15
lines changed

src/mcp/server.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,18 @@ pub trait MyContract {
450450
}
451451
});
452452

453+
it('rejects invalid network parameter', async () => {
454+
const result = await client.callTool({
455+
name: 'get_balance',
456+
arguments: { address: 'klv1test', network: 'staging' },
457+
});
458+
459+
const content = result.content as Array<{ type: string; text: string }>;
460+
expect(content[0].text).toContain('Invalid network');
461+
expect(content[0].text).toContain('staging');
462+
expect(content[0].text).toContain('mainnet, testnet, devnet, local');
463+
});
464+
453465
it('get_balance returns formatted result', async () => {
454466
mockFetch.mockResolvedValueOnce(
455467
jsonResponse({ data: { balance: 5000000 }, error: '', code: 'successful' })

src/mcp/server.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ import type { KleverNetwork, VMQueryRequest } from '../chain/types.js';
1919

2020
export type ServerProfile = 'local' | 'public';
2121

22+
const VALID_NETWORKS = new Set<string>(['mainnet', 'testnet', 'devnet', 'local']);
23+
24+
function validateNetwork(network: string | undefined): KleverNetwork | undefined {
25+
if (network === undefined) return undefined;
26+
if (!VALID_NETWORKS.has(network)) {
27+
throw new Error(
28+
`Invalid network "${network}". Valid options: mainnet, testnet, devnet, local.`
29+
);
30+
}
31+
return network as KleverNetwork;
32+
}
33+
2234
interface ExecError {
2335
message: string;
2436
stderr: string;
@@ -1583,7 +1595,7 @@ export class KleverMCPServer {
15831595
const balance = await this.chainClient.getBalance(
15841596
address,
15851597
assetId,
1586-
network as KleverNetwork | undefined
1598+
validateNetwork(network)
15871599
);
15881600

15891601
return {
@@ -1618,7 +1630,7 @@ export class KleverMCPServer {
16181630

16191631
const account = await this.chainClient.getAccount(
16201632
address,
1621-
network as KleverNetwork | undefined
1633+
validateNetwork(network)
16221634
);
16231635

16241636
return {
@@ -1648,7 +1660,7 @@ export class KleverMCPServer {
16481660

16491661
const asset = await this.chainClient.getAssetInfo(
16501662
assetId,
1651-
network as KleverNetwork | undefined
1663+
validateNetwork(network)
16521664
);
16531665

16541666
return {
@@ -1686,7 +1698,7 @@ export class KleverMCPServer {
16861698

16871699
const result = await this.chainClient.querySmartContract(
16881700
request,
1689-
network as KleverNetwork | undefined
1701+
validateNetwork(network)
16901702
);
16911703

16921704
return {
@@ -1717,7 +1729,7 @@ export class KleverMCPServer {
17171729

17181730
const tx = await this.chainClient.getTransaction(
17191731
hash,
1720-
network as KleverNetwork | undefined
1732+
validateNetwork(network)
17211733
);
17221734

17231735
return {
@@ -1747,7 +1759,7 @@ export class KleverMCPServer {
17471759

17481760
const block = await this.chainClient.getBlock(
17491761
nonce,
1750-
network as KleverNetwork | undefined
1762+
validateNetwork(network)
17511763
);
17521764

17531765
return {
@@ -1773,7 +1785,7 @@ export class KleverMCPServer {
17731785
console.error(`[MCP] list_validators: network=${network || 'default'}`);
17741786

17751787
const validators = await this.chainClient.listValidators(
1776-
network as KleverNetwork | undefined
1788+
validateNetwork(network)
17771789
);
17781790

17791791
return {
@@ -1809,7 +1821,7 @@ export class KleverMCPServer {
18091821

18101822
const nonce = await this.chainClient.getNonce(
18111823
sender,
1812-
network as KleverNetwork | undefined
1824+
validateNetwork(network)
18131825
);
18141826

18151827
const contract: Array<{ type: number; parameter: Record<string, unknown> }> = [
@@ -1825,7 +1837,7 @@ export class KleverMCPServer {
18251837

18261838
const txResult = await this.chainClient.buildTransaction(
18271839
{ type: 0, sender, nonce, contract },
1828-
network as KleverNetwork | undefined
1840+
validateNetwork(network)
18291841
);
18301842

18311843
return {
@@ -1872,7 +1884,7 @@ export class KleverMCPServer {
18721884

18731885
const nonce = await this.chainClient.getNonce(
18741886
sender,
1875-
network as KleverNetwork | undefined
1887+
validateNetwork(network)
18761888
);
18771889

18781890
const data = [wasmHex, ...(initArgs || [])];
@@ -1888,7 +1900,7 @@ export class KleverMCPServer {
18881900

18891901
const txResult = await this.chainClient.buildTransaction(
18901902
{ type: 9, sender, nonce, contract, data },
1891-
network as KleverNetwork | undefined
1903+
validateNetwork(network)
18921904
);
18931905

18941906
return {
@@ -1942,7 +1954,7 @@ export class KleverMCPServer {
19421954

19431955
const nonce = await this.chainClient.getNonce(
19441956
sender,
1945-
network as KleverNetwork | undefined
1957+
validateNetwork(network)
19461958
);
19471959

19481960
const data = [funcName, ...(scArgs || [])];
@@ -1960,7 +1972,7 @@ export class KleverMCPServer {
19601972

19611973
const txResult = await this.chainClient.buildTransaction(
19621974
{ type: 9, sender, nonce, contract, data },
1963-
network as KleverNetwork | undefined
1975+
validateNetwork(network)
19641976
);
19651977

19661978
return {
@@ -2007,7 +2019,7 @@ export class KleverMCPServer {
20072019

20082020
const nonce = await this.chainClient.getNonce(
20092021
sender,
2010-
network as KleverNetwork | undefined
2022+
validateNetwork(network)
20112023
);
20122024

20132025
const contract: Array<{ type: number; parameter: Record<string, unknown> }> = [
@@ -2021,7 +2033,7 @@ export class KleverMCPServer {
20212033

20222034
const txResult = await this.chainClient.buildTransaction(
20232035
{ type: 2, sender, nonce, contract },
2024-
network as KleverNetwork | undefined
2036+
validateNetwork(network)
20252037
);
20262038

20272039
return {

0 commit comments

Comments
 (0)