Skip to main content
Glama
Seitrace

Seitrace Insights MCP Server

Official
by Seitrace
download_abi_test.mjs12.3 kB
import { dbg } from './utils.mjs'; /* global process */ /** * Comprehensive test suite for the download_abi action * Tests various scenarios including valid contracts, invalid contracts, error handling, etc. */ export const testDownloadAbiAction = async (client) => { dbg('\n🧪 Starting download_abi action comprehensive tests...\n'); const testResults = { passed: 0, failed: 0, errors: [] }; const runTest = async (testName, testFn) => { try { dbg(`\n📋 Running test: ${testName}`); await testFn(); testResults.passed++; dbg(`✅ ${testName} - PASSED`); } catch (error) { testResults.failed++; testResults.errors.push({ test: testName, error: error.message }); dbg(`❌ ${testName} - FAILED: ${error.message}`); } }; // Test 1: Valid verified contract (AggregatorHelper on pacific-1) await runTest('Valid verified contract - AggregatorHelper', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { contract_address: '0x8d72Fa8b37F8A97CC0cE5Ee4077806e3b63dE9d0', chain: 'pacific-1' } } }); const response = JSON.parse(result.content[0].text); if (response.error) { throw new Error(`Expected success but got error: ${JSON.stringify(response.error)}`); } // Verify response contains ONLY the "abi" field const responseKeys = Object.keys(response); if (responseKeys.length !== 1 || responseKeys[0] !== 'abi') { throw new Error(`Expected response to contain only "abi" field, but got: ${responseKeys.join(', ')}`); } if (!response.abi || !Array.isArray(response.abi)) { throw new Error('Expected ABI array in response'); } // Verify ABI contains expected functions const abiMethods = response.abi.filter(item => item.type === 'function').map(item => item.name); const expectedMethods = ['maxScraps', 'owner', 'setMaxScraps', 'swapExactInput', 'swapExactOutput']; for (const method of expectedMethods) { if (!abiMethods.includes(method)) { throw new Error(`Expected method '${method}' not found in ABI`); } } dbg('✓ Response contains only "abi" field'); dbg('✓ ABI methods found:', abiMethods.length); }); // Test 1.5: Explicit test for "abi-only" response requirement await runTest('Response contains ONLY abi field (resolver behavior)', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { contract_address: '0x8d72Fa8b37F8A97CC0cE5Ee4077806e3b63dE9d0', chain: 'pacific-1' } } }); const response = JSON.parse(result.content[0].text); if (response.error) { throw new Error(`Expected success but got error: ${JSON.stringify(response.error)}`); } // Critical test: Verify response has EXACTLY one key and it's "abi" const responseKeys = Object.keys(response); if (responseKeys.length !== 1) { throw new Error(`Response should have exactly 1 key, but has ${responseKeys.length}: [${responseKeys.join(', ')}]`); } if (responseKeys[0] !== 'abi') { throw new Error(`Response should have only "abi" key, but has: "${responseKeys[0]}"`); } // Verify it's not returning other fields that might be in the full contract response const forbiddenFields = [ 'source_code', 'name', 'compiler_version', 'optimization_enabled', 'is_verified', 'deployed_bytecode', 'constructor_args', 'license_type', 'creation_bytecode', 'additional_sources', 'certified' ]; for (const field of forbiddenFields) { if (field in response) { throw new Error(`Response should not contain "${field}" field (resolver should filter it out)`); } } dbg('✓ Confirmed: Response contains ONLY "abi" field'); dbg('✓ Confirmed: No other contract metadata fields present'); }); // Test 2: Different chain - atlantic-2 await runTest('Valid contract on atlantic-2', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'atlantic-2', contract_address: '0x1234567890123456789012345678901234567890' // Example address } } }); const response = JSON.parse(result.content[0].text); // This may return an error if contract doesn't exist, which is expected dbg('Atlantic-2 test result:', response.error ? 'Error (expected)' : 'Success'); }); // Test 3: Invalid contract address format await runTest('Invalid contract address format', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'pacific-1', contract_address: 'invalid_address' } } }); const response = JSON.parse(result.content[0].text); if (!response.error) { throw new Error('Expected error for invalid address format'); } dbg('Invalid address error:', response.error); }); // Test 4: Non-existent contract address await runTest('Non-existent contract address', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'pacific-1', contract_address: '0x0000000000000000000000000000000000000001' } } }); const response = JSON.parse(result.content[0].text); if (!response.error) { throw new Error('Expected error for non-existent contract'); } dbg('Non-existent contract error:', response.error); }); // Test 5: Missing required parameters await runTest('Missing chain parameter', async () => { try { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { contract_address: '0x8d72Fa8b37F8A97CC0cE5Ee4077806e3b63dE9d0' } } }); const response = JSON.parse(result.content[0].text); if (!response.error) { throw new Error('Expected error for missing chain parameter'); } dbg('Missing chain error:', response.error); } catch (error) { // MCP might throw an error before reaching the action if (error.message.includes('chain') || error.message.includes('required')) { dbg('Expected validation error caught:', error.message); } else { throw error; } } }); // Test 6: Missing contract_address parameter await runTest('Missing contract_address parameter', async () => { try { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'pacific-1' } } }); const response = JSON.parse(result.content[0].text); if (!response.error) { throw new Error('Expected error for missing contract_address parameter'); } dbg('Missing contract_address error:', response.error); } catch (error) { // MCP might throw an error before reaching the action if (error.message.includes('contract_address') || error.message.includes('required')) { dbg('Expected validation error caught:', error.message); } else { throw error; } } }); // Test 7: Invalid chain parameter await runTest('Invalid chain parameter', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'invalid-chain', contract_address: '0x8d72Fa8b37F8A97CC0cE5Ee4077806e3b63dE9d0' } } }); const response = JSON.parse(result.content[0].text); if (!response.error) { throw new Error('Expected error for invalid chain'); } dbg('Invalid chain error:', response.error); }); // Test 8: Unverified contract (if we can find one) await runTest('Unverified contract handling', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'pacific-1', contract_address: '0x1111111111111111111111111111111111111111' } } }); const response = JSON.parse(result.content[0].text); // Should either return error or indicate unverified status dbg('Unverified contract result:', response.error ? 'Error (expected)' : 'Unexpected success'); }); // Test 9: Response format validation await runTest('Response format validation', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'pacific-1', contract_address: '0x8d72Fa8b37F8A97CC0cE5Ee4077806e3b63dE9d0' } } }); const response = JSON.parse(result.content[0].text); if (response.error) { throw new Error(`Unexpected error: ${JSON.stringify(response.error)}`); } // Validate response structure if (typeof response !== 'object') { throw new Error('Response is not an object'); } if (!Object.prototype.hasOwnProperty.call(response, 'abi')) { throw new Error('Response missing abi field'); } if (!Array.isArray(response.abi)) { throw new Error('ABI is not an array'); } // Validate ABI structure for (const item of response.abi) { if (!item.type) { throw new Error('ABI item missing type field'); } if (item.type === 'function' && !item.name) { throw new Error('Function ABI item missing name field'); } } dbg('Response format validation passed'); }); // Test 10: Edge case - empty string address await runTest('Empty string contract address', async () => { const result = await client.callTool({ name: 'invoke_resource_action', arguments: { resource: 'smart_contract', action: 'download_abi', payload: { chain: 'pacific-1', contract_address: '' } } }); const response = JSON.parse(result.content[0].text); if (!response.error) { throw new Error('Expected error for empty address'); } dbg('Empty address error:', response.error); }); // Summary dbg('\n📊 Test Summary:'); dbg(`✅ Passed: ${testResults.passed}`); dbg(`❌ Failed: ${testResults.failed}`); dbg(`📈 Success Rate: ${((testResults.passed / (testResults.passed + testResults.failed)) * 100).toFixed(1)}%`); if (testResults.errors.length > 0) { dbg('\n🚨 Failed Tests:'); testResults.errors.forEach(({ test, error }) => { dbg(` - ${test}: ${error}`); }); } return testResults; }; // Example usage for standalone testing export const runStandaloneDownloadAbiTests = async () => { dbg('🚀 Starting standalone download_abi tests...'); // Mock client for demonstration const mockClient = { callTool: async ({ name, arguments: args }) => { dbg(`Mock call: ${name} with`, args); return { content: [{ text: JSON.stringify({ error: 'Mock client - implement real MCP client for actual testing' }) }] }; } }; await testDownloadAbiAction(mockClient); }; // If running directly if (import.meta.url === `file://${process.argv[1]}`) { runStandaloneDownloadAbiTests().catch(dbg); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Seitrace/seitrace-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server