devion-mcp-server
Version:
MCP server for Devion blockchain infrastructure - AI-native blockchain data access for developers and AI agents
181 lines • 7.16 kB
JavaScript
import { DevionSDK } from 'devion-sdk';
import { z } from 'zod';
const NETWORKS = [
'ethereum-mainnet',
'base-mainnet',
'arbitrum-mainnet',
'polygon-mainnet',
'base-sepolia',
'arbitrum-sepolia'
];
export const getTransactionDetails = {
name: 'get_transaction_details',
description: 'Get detailed information about a specific transaction by its hash',
inputSchema: {
type: 'object',
properties: {
tx_hash: {
type: 'string',
description: 'Transaction hash (0x...)',
pattern: '^0x[a-fA-F0-9]{64}$'
},
network: {
type: 'string',
enum: NETWORKS,
description: 'Blockchain network to query (defaults to ethereum-mainnet)'
},
include_receipt: {
type: 'boolean',
description: 'Include transaction receipt with logs and gas usage',
default: true
}
},
required: ['tx_hash']
},
async handler(args) {
const schema = z.object({
tx_hash: z.string().regex(/^0x[a-fA-F0-9]{64}$/, 'Invalid transaction hash'),
network: z.enum(NETWORKS).default('ethereum-mainnet'),
include_receipt: z.boolean().default(true)
});
const { tx_hash, network, include_receipt } = schema.parse(args);
const sdk = new DevionSDK({
apiKey: process.env.DEVION_API_KEY,
baseURL: 'https://api.devion.dev',
network: network
});
try {
const tx = await sdk.rpc('eth_getTransactionByHash', [tx_hash]);
if (!tx) {
return {
success: false,
error: 'Transaction not found',
details: { tx_hash, network }
};
}
const result = {
success: true,
data: {
transaction: {
hash: tx.hash,
from: tx.from,
to: tx.to,
value: tx.value,
value_eth: sdk.formatUnits(tx.value || '0', 18),
gas: parseInt(tx.gas, 16),
gas_price: tx.gasPrice ? parseInt(tx.gasPrice, 16) : null,
max_fee_per_gas: tx.maxFeePerGas ? parseInt(tx.maxFeePerGas, 16) : null,
max_priority_fee_per_gas: tx.maxPriorityFeePerGas ? parseInt(tx.maxPriorityFeePerGas, 16) : null,
nonce: parseInt(tx.nonce, 16),
block_number: tx.blockNumber ? parseInt(tx.blockNumber, 16) : null,
block_hash: tx.blockHash,
transaction_index: tx.transactionIndex ? parseInt(tx.transactionIndex, 16) : null,
input: tx.input,
type: tx.type ? parseInt(tx.type, 16) : 0
},
network,
timestamp: new Date().toISOString()
}
};
if (include_receipt && tx.blockNumber) {
try {
const receipt = await sdk.rpc('eth_getTransactionReceipt', [tx_hash]);
if (receipt) {
result.data.receipt = {
status: receipt.status === '0x1' ? 'success' : 'failed',
gas_used: parseInt(receipt.gasUsed, 16),
cumulative_gas_used: parseInt(receipt.cumulativeGasUsed, 16),
effective_gas_price: receipt.effectiveGasPrice ? parseInt(receipt.effectiveGasPrice, 16) : null,
logs: receipt.logs || [],
logs_count: receipt.logs ? receipt.logs.length : 0
};
}
}
catch (receiptError) {
result.data.receipt_error = 'Could not fetch receipt';
}
}
return result;
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
details: {
tx_hash,
network,
timestamp: new Date().toISOString()
}
};
}
}
};
export const getTransactions = {
name: 'get_recent_transactions',
description: 'Get recent transactions for a specific address (note: requires transaction indexing service)',
inputSchema: {
type: 'object',
properties: {
address: {
type: 'string',
description: 'Ethereum address to get transactions for (0x...)',
pattern: '^0x[a-fA-F0-9]{40}$'
},
network: {
type: 'string',
enum: NETWORKS,
description: 'Blockchain network to query (defaults to ethereum-mainnet)'
},
limit: {
type: 'number',
description: 'Maximum number of transactions to return (1-100)',
minimum: 1,
maximum: 100,
default: 10
}
},
required: ['address']
},
async handler(args) {
const schema = z.object({
address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid Ethereum address'),
network: z.enum(NETWORKS).default('ethereum-mainnet'),
limit: z.number().min(1).max(100).default(10)
});
const { address, network } = schema.parse(args);
const sdk = new DevionSDK({
apiKey: process.env.DEVION_API_KEY,
baseURL: 'https://api.devion.dev',
network: network
});
try {
const nonce = await sdk.getTransactionCount(address);
return {
success: true,
data: {
address,
network,
current_nonce: typeof nonce === 'string' ? parseInt(nonce, 16) : nonce,
note: 'This tool requires integration with a transaction indexing service for full functionality',
suggestion: 'Use block explorers like Etherscan API for comprehensive transaction history',
alternatives: [
'Check specific transaction hashes with get_transaction_details',
'Monitor recent blocks with get_latest_block for new transactions'
]
}
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
details: {
address,
network,
timestamp: new Date().toISOString()
}
};
}
}
};
//# sourceMappingURL=transactions.js.map