Skip to main content
Glama
transaction.tsβ€’6.03 kB
import { GuardEngine } from '../core/guard-engine.js' import { TxSimulateRequest, TxSimulateResponse, TxExecuteRequest, TxExecuteResponse, X402PaymentRequired, McpResponse } from '../types/index.js' export class TransactionTools { constructor(private guardEngine: GuardEngine) {} async handleTool(name: string, args: any): Promise<McpResponse | X402PaymentRequired> { switch (name) { case 'tx.simulate': return await this.simulate(args as TxSimulateRequest) case 'tx.execute': return await this.execute(args as TxExecuteRequest) default: throw new Error(`Unknown transaction tool: ${name}`) } } private async simulate(request: TxSimulateRequest): Promise<McpResponse<TxSimulateResponse>> { try { // Simulate the transaction const simulation = await this.performSimulation(request) // Check guardrails const guardResult = this.guardEngine.validateSimulation(simulation, request.txParams || {}) // Update simulation with guard results simulation.guardsTriggered = guardResult.triggeredGuards // If guards failed, return error if (!guardResult.passed) { return { success: false, error: { code: 'GUARD_VIOLATION', message: `Simulation blocked by guards: ${guardResult.triggeredGuards.join(', ')}`, details: { triggeredGuards: guardResult.triggeredGuards, warnings: guardResult.warnings } }, metadata: { timestamp: new Date().toISOString() } } } return { success: true, data: simulation, metadata: { timestamp: new Date().toISOString(), requestId: `simulate_${Date.now()}` } } } catch (error) { return { success: false, error: { code: 'SIMULATION_ERROR', message: error instanceof Error ? error.message : String(error) }, metadata: { timestamp: new Date().toISOString() } } } } private async execute(request: TxExecuteRequest): Promise<McpResponse<TxExecuteResponse> | X402PaymentRequired> { try { // Check guardrails first const guardResult = this.guardEngine.validateExecution(request) if (!guardResult.passed) { return { success: false, error: { code: 'GUARD_VIOLATION', message: `Transaction blocked by guards: ${guardResult.triggeredGuards.join(', ')}`, details: { triggeredGuards: guardResult.triggeredGuards, warnings: guardResult.warnings } }, metadata: { timestamp: new Date().toISOString() } } } // Check if payment is required (x402) const requiresPayment = this.shouldRequirePayment(request) if (requiresPayment && !request.paymentProof) { // Return HTTP 402 Payment Required return { invoiceId: `inv_${Date.now()}`, amount: '0.50', asset: 'USDC', receiver: process.env.X402_RECEIVER || '0x0000000000000000000000000000000000000000', description: 'Transaction execution fee' } as X402PaymentRequired } // Verify payment proof if provided if (request.paymentProof) { const paymentValid = await this.verifyPaymentProof(request.paymentProof) if (!paymentValid) { return { success: false, error: { code: 'INVALID_PAYMENT_PROOF', message: 'Payment proof verification failed' }, metadata: { timestamp: new Date().toISOString() } } } } // Execute the transaction const execution = await this.performExecution(request) return { success: true, data: execution, metadata: { timestamp: new Date().toISOString(), requestId: `execute_${Date.now()}` } } } catch (error) { return { success: false, error: { code: 'EXECUTION_ERROR', message: error instanceof Error ? error.message : String(error) }, metadata: { timestamp: new Date().toISOString() } } } } private async performSimulation(request: TxSimulateRequest): Promise<TxSimulateResponse> { // This would integrate with actual transaction simulation // For now, return mock data const baseFee = 0.001 // 0.001 ETH base fee const gasPrice = 20 // 20 gwei const gasLimit = 150000 // Standard gas limit const feeUsd = baseFee * 2000 // Assuming ETH = $2000 const slippagePct = Math.random() * 0.5 // Random slippage between 0-0.5% return { ok: true, est: { feeUsd, slippagePct, avgPrice: 2000 // Mock ETH price }, guardsTriggered: [] } } private async performExecution(request: TxExecuteRequest): Promise<TxExecuteResponse> { // This would integrate with actual transaction execution // For now, return mock data const mockTxHash = `0x${Math.random().toString(16).substring(2, 66)}` return { status: 'submitted', txHash: mockTxHash, route: 'AURA:uniswap-v3', notes: 'Transaction submitted successfully' } } private shouldRequirePayment(request: TxExecuteRequest): boolean { // Determine if payment is required based on transaction value, type, etc. // For demo purposes, require payment for transactions over $100 const txValue = request.txParams?.value || 0 return txValue > 100 } private async verifyPaymentProof(paymentProof: any): Promise<boolean> { // This would verify the payment proof on-chain // For now, return true for demo purposes return true } }

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/antidump/MCP'

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