import { z } from 'zod';
import { DataiClient } from '../utils/api-client.js';
import { WalletAddressSchema } from '../utils/validation.js';
import { DataAIError, ValidationError, APIError, NetworkError, TimeoutError } from '../utils/error-handler.js';
/**
* Tool 1: Get All User DeFi Positions
*
* COMPREHENSIVE DESCRIPTION:
* This tool fetches comprehensive DeFi positions for a specific wallet address across ALL supported
* blockchain networks. It provides a complete portfolio overview including positions in lending protocols,
* liquidity pools, yield farming, staking, and other DeFi activities across multiple chains.
*
* USE CASES:
* - Complete DeFi portfolio analysis
* - Cross-chain position aggregation
* - Risk assessment and diversification analysis
* - Tax reporting and compliance
* - Portfolio performance tracking
* - DeFi protocol exposure analysis
*
* SUPPORTED CHAINS:
* - eth (Ethereum Mainnet)
* - arb (Arbitrum)
* - matic (Polygon)
* - avax (Avalanche)
* - bsc (Binance Smart Chain)
* - base (Base)
* - op (Optimism)
* - blast (Blast)
* - linea (Linea)
* - manta (Manta)
*
* SUPPORTED PROTOCOLS:
* - Uniswap V2/V3/V4 (liquidity pools, farming)
* - Aave V2/V3 (lending, borrowing)
* - Compound (lending, borrowing)
* - MakerDAO (CDP, DSR)
* - Curve (liquidity pools, gauges)
* - Balancer (liquidity pools, farming)
* - SushiSwap (liquidity pools, farming)
* - QuickSwap (liquidity pools, farming)
* - TraderJoe (liquidity pools, farming)
* - Pancake (liquidity pools, farming)
* - 1inch (liquidity pools)
* - Superfluid (streaming)
* - Sablier (vesting)
* - Element (fixed yield)
* - Hop Protocol (bridge liquidity)
* - ShibaSwap (liquidity pools)
*
* RESPONSE FORMAT:
* Returns an array of position objects grouped by chain and protocol:
* [
* {
* "chain": "eth",
* "protocol": "uniswap-v3",
* "positions": [
* {
* "type": "liquidity",
* "pool": "USDC/ETH",
* "value_usd": 15420.50,
* "tokens": [...],
* "rewards": [...]
* }
* ]
* }
* ]
*
* SECURITY CONSIDERATIONS:
* - Wallet addresses are validated using Ethereum address format
* - No sensitive data is logged or stored
* - All requests are authenticated via API key
* - Rate limiting applied to prevent API abuse
* - Response data is sanitized and validated
*
* PERFORMANCE:
* - Typical response time: 3-8 seconds (cross-chain aggregation)
* - Cached data may be up to 5 minutes old
* - Timeout configured for 180 seconds
* - Automatic retry on transient failures
* - Data truncation available for debugging
*
* ERROR HANDLING:
* - Invalid wallet address: Returns validation error with format guidance
* - Network timeout: Returns timeout error with retry suggestion
* - API rate limit: Returns rate limit error with backoff time
* - Invalid API key: Returns authentication error
* - Wallet not found: Returns empty positions array
* - Protocol errors: Returns specific protocol error details
*
* EXAMPLES:
*
* Example 1 - Active DeFi user:
* Input: { wallet: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" }
* Output: Array with 15+ positions across 8 chains and 12 protocols
*
* Example 2 - New wallet:
* Input: { wallet: "0x0000000000000000000000000000000000000000" }
* Output: [] (empty array)
*
* Example 3 - Single protocol user:
* Input: { wallet: "0x09CF915e195aF33FA7B932C253352Ae9FBdB0106" }
* Output: Array with positions primarily in Uniswap and Aave
*/
export function createGetAllUserDeFiPositionsTool(client: DataiClient) {
return {
name: "get_all_defi_positions",
description: "Get comprehensive DeFi positions for a wallet across ALL supported blockchain networks and protocols. Provides complete portfolio overview including lending, liquidity pools, yield farming, staking, and other DeFi activities across 10+ chains and 15+ protocols.",
// Enhanced parameter documentation
parameters: z.object({
wallet: WalletAddressSchema.describe("Ethereum wallet address (42-character hex string starting with 0x) to get comprehensive DeFi positions for. Example: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
}),
// Tool annotations for better MCP client understanding - TEMPORARILY COMMENTED OUT
/*
annotations: {
readOnlyHint: true, // This tool only reads data, doesn't modify anything
destructiveHint: false, // Safe operation, no destructive actions
openWorldHint: true, // Open set of protocols and chains (expanding)
idempotentHint: true, // Same inputs always produce same results (within cache window)
streamingHint: false, // Returns complete response, no streaming
title: "All DeFi Positions",
category: "Portfolio Analysis",
tags: ["defi", "portfolio", "cross-chain", "comprehensive", "positions", "protocols"]
},
*/
execute: async (args: { wallet: string }, context: { log: any }) => {
const { log } = context;
const startTime = Date.now();
const executionId = crypto.randomUUID().slice(0, 8);
log.info("Starting get_all_defi_positions", {
executionId,
wallet: args.wallet
});
try {
// Validate wallet address
const validatedArgs = { wallet: WalletAddressSchema.parse(args.wallet) };
// Make API request
const response = await client.getAllUserDeFiPositions(validatedArgs.wallet);
const duration = Date.now() - startTime;
const positionCount = Array.isArray(response.data) ? response.data.length : 0;
log.info("DeFi positions fetched successfully", {
executionId,
wallet: validatedArgs.wallet,
positionCount,
duration: `${duration}ms`
});
// Return actual API response data
return {
content: [{
type: "text" as const,
text: JSON.stringify(response.data, null, 2)
}]
};
} catch (error: any) {
const duration = Date.now() - startTime;
log.error("Failed to fetch all DeFi positions", {
executionId,
wallet: args.wallet,
duration: `${duration}ms`,
error: error.message,
errorType: error.constructor.name,
errorCode: error.code || 'UNKNOWN',
success: false
});
// Transform error for user-friendly response with specific guidance
if (error instanceof ValidationError) {
throw new DataAIError(
`Invalid wallet address: ${args.wallet}. Please provide a valid Ethereum address (42 characters, starting with 0x).`,
'VALIDATION_ERROR'
);
} else if (error instanceof TimeoutError) {
throw new DataAIError(
`Request timed out after ${duration}ms. Cross-chain data aggregation may take longer during high load. Please try again in a few moments.`,
'TIMEOUT_ERROR'
);
} else if (error instanceof NetworkError) {
throw new DataAIError(
'Network error occurred while fetching DeFi positions. Please check your connection and try again.',
'NETWORK_ERROR'
);
} else if (error instanceof APIError) {
if (error.message.includes('404')) {
throw new DataAIError(
`No DeFi positions found for wallet ${args.wallet}. The wallet may be new or not active in DeFi protocols.`,
'NOT_FOUND'
);
} else if (error.message.includes('429')) {
throw new DataAIError(
'Rate limit exceeded. Please wait a moment before making another request.',
'RATE_LIMIT_EXCEEDED'
);
} else if (error.message.includes('401') || error.message.includes('403')) {
throw new DataAIError(
'Authentication failed. Please check your API credentials.',
'AUTHENTICATION_ERROR'
);
} else {
throw new DataAIError(`API error: ${error.message}`, 'API_ERROR');
}
} else {
throw new DataAIError(
`Failed to fetch DeFi positions: ${error.message}. Please try again or contact support if the issue persists.`,
'UNKNOWN_ERROR'
);
}
}
}
};
}