[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GNXFDBCYB2DA10TTYFCZSB":3,"skill-same:01M6GNXFDBCYB2DA10TTYFCZSB":93},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":6,"ownerHtmlUrl":47,"ownerBlogUrl":48,"ownerDescription":49,"updatedAt":50,"install":51,"resources":64},"01M6GNXFDBCYB2DA10TTYFCZSB","web3-defi-protocols",null,"Integrate DeFi protocols into SpoonOS agents. Use when building lending integrations (Aave, Compound), DEX aggregators (1inch, CoW Protocol), or yield strategies.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",80,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"protocols","defi","web3","web3 defi protocols","1inch","when","cow protocol","yield strategies","strategies","aave","yield","compound","protocol","dex","integrate","use","integrations","lending","2026-11-10 10:12:30",false,"---\nname: web3-defi-protocols\ndescription: Integrate DeFi protocols into SpoonOS agents. Use when building lending integrations (Aave, Compound), DEX aggregators (1inch, CoW Protocol), or yield strategies.\n---\n\n# DeFi Protocol Integration\n\nConnect SpoonOS agents to major DeFi protocols.\n\n## Supported Protocols\n\n| Protocol | Type | Chains |\n|----------|------|--------|\n| Aave V3 | Lending | ETH, Polygon, Arbitrum, Optimism, Base |\n| Compound V3 | Lending | ETH, Polygon, Arbitrum, Base |\n| 1inch | DEX Aggregator | All major EVM |\n| CoW Protocol | MEV-protected swaps | ETH, Gnosis |\n| Uniswap V3 | DEX | All major EVM |\n\n## Aave V3 Integration\n\n### Contract Addresses\n\n```python\nAAVE_V3_ADDRESSES = {\n    \"ethereum\": {\n        \"pool\": \"0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2\",\n        \"pool_data_provider\": \"0x7B4EB56E7CD4b454BA8ff71E4518426369a138a3\",\n        \"oracle\": \"0x54586bE62E3c3580375aE3723C145253060Ca0C2\"\n    },\n    \"polygon\": {\n        \"pool\": \"0x794a61358D6845594F94dc1DB02A252b5b4814aD\",\n        \"pool_data_provider\": \"0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654\",\n        \"oracle\": \"0xb023e699F5a33916Ea823A16485e259257cA8Bd1\"\n    },\n    \"arbitrum\": {\n        \"pool\": \"0x794a61358D6845594F94dc1DB02A252b5b4814aD\",\n        \"pool_data_provider\": \"0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654\",\n        \"oracle\": \"0xb56c2F0B653B2e0b10C9b928C8580Ac5Df02C7C7\"\n    },\n    \"base\": {\n        \"pool\": \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\",\n        \"pool_data_provider\": \"0x2d8A3C5677189723C4cB8873CfC9C8976FDF38Ac\",\n        \"oracle\": \"0x2Cc0Fc26eD4563A5ce5e8bdcfe1A2878676Ae156\"\n    }\n}\n```\n\n### Aave Tool Implementation\n\n```python\n# scripts\u002Faave_lending.py\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\nfrom web3 import Web3\nimport json\n\nAAVE_POOL_ABI = [...]  # See references\u002Faave-abi.md\n\nclass AaveLendingTool(BaseTool):\n    name: str = \"aave_lending\"\n    description: str = \"Supply, borrow, repay on Aave V3\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"action\": {\n                \"type\": \"string\",\n                \"enum\": [\"supply\", \"borrow\", \"repay\", \"withdraw\", \"positions\"],\n                \"description\": \"Lending action to perform\"\n            },\n            \"asset\": {\"type\": \"string\", \"description\": \"Token symbol (USDC, WETH, etc.)\"},\n            \"amount\": {\"type\": \"string\", \"description\": \"Amount in token units\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"ethereum\"}\n        },\n        \"required\": [\"action\"]\n    })\n\n    async def execute(self, action: str, asset: str = None,\n                      amount: str = None, chain: str = \"ethereum\") -> str:\n        if action == \"positions\":\n            return await self._get_positions(chain)\n        elif action == \"supply\":\n            return await self._supply(asset, amount, chain)\n        elif action == \"borrow\":\n            return await self._borrow(asset, amount, chain)\n        elif action == \"repay\":\n            return await self._repay(asset, amount, chain)\n        elif action == \"withdraw\":\n            return await self._withdraw(asset, amount, chain)\n\n    async def _get_positions(self, chain: str) -> str:\n        \"\"\"Get user's Aave positions.\"\"\"\n        addresses = AAVE_V3_ADDRESSES[chain]\n        w3 = Web3(Web3.HTTPProvider(RPC_URLS[chain]))\n\n        pool_data = w3.eth.contract(\n            address=addresses[\"pool_data_provider\"],\n            abi=POOL_DATA_PROVIDER_ABI\n        )\n\n        user_address = os.getenv(\"WALLET_ADDRESS\")\n        reserves = pool_data.functions.getUserReservesData(\n            addresses[\"pool\"],\n            user_address\n        ).call()\n\n        positions = []\n        for reserve in reserves:\n            if reserve[1] > 0 or reserve[2] > 0:  # supplied or borrowed\n                positions.append({\n                    \"asset\": reserve[0],\n                    \"supplied\": reserve[1] \u002F 1e18,\n                    \"borrowed\": reserve[2] \u002F 1e18\n                })\n\n        return json.dumps({\"positions\": positions}, indent=2)\n```\n\n## 1inch Integration\n\n### API Configuration\n\n```python\nONEINCH_API = {\n    \"base_url\": \"https:\u002F\u002Fapi.1inch.dev\",\n    \"swap_endpoint\": \"\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fswap\",\n    \"quote_endpoint\": \"\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fquote\",\n    \"tokens_endpoint\": \"\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Ftokens\"\n}\n\nCHAIN_IDS = {\n    \"ethereum\": 1,\n    \"polygon\": 137,\n    \"arbitrum\": 42161,\n    \"optimism\": 10,\n    \"base\": 8453\n}\n```\n\n### 1inch Swap Tool\n\n```python\n# scripts\u002Foneinch_swap.py\nimport aiohttp\nimport os\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\n\nclass OneInchSwapTool(BaseTool):\n    name: str = \"oneinch_swap\"\n    description: str = \"Get swap quotes and execute via 1inch aggregator\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"action\": {\"type\": \"string\", \"enum\": [\"quote\", \"swap\"]},\n            \"from_token\": {\"type\": \"string\", \"description\": \"Source token address\"},\n            \"to_token\": {\"type\": \"string\", \"description\": \"Destination token address\"},\n            \"amount\": {\"type\": \"string\", \"description\": \"Amount in wei\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"ethereum\"},\n            \"slippage\": {\"type\": \"number\", \"default\": 1, \"description\": \"Slippage %\"}\n        },\n        \"required\": [\"action\", \"from_token\", \"to_token\", \"amount\"]\n    })\n\n    async def execute(self, action: str, from_token: str, to_token: str,\n                      amount: str, chain: str = \"ethereum\", slippage: float = 1) -> str:\n        chain_id = CHAIN_IDS[chain]\n        api_key = os.getenv(\"ONEINCH_API_KEY\")\n\n        headers = {\n            \"Authorization\": f\"Bearer {api_key}\",\n            \"Content-Type\": \"application\u002Fjson\"\n        }\n\n        if action == \"quote\":\n            url = f\"{ONEINCH_API['base_url']}\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fquote\"\n            params = {\n                \"src\": from_token,\n                \"dst\": to_token,\n                \"amount\": amount\n            }\n        else:\n            url = f\"{ONEINCH_API['base_url']}\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fswap\"\n            params = {\n                \"src\": from_token,\n                \"dst\": to_token,\n                \"amount\": amount,\n                \"from\": os.getenv(\"WALLET_ADDRESS\"),\n                \"slippage\": slippage\n            }\n\n        async with aiohttp.ClientSession() as session:\n            async with session.get(url, headers=headers, params=params) as resp:\n                if resp.status != 200:\n                    error = await resp.text()\n                    return f\"Error: {error}\"\n\n                data = await resp.json()\n\n                if action == \"quote\":\n                    return self._format_quote(data)\n                else:\n                    return self._format_swap(data)\n\n    def _format_quote(self, data: dict) -> str:\n        return f\"\"\"\n1inch Quote:\n- From: {data['srcToken']['symbol']}\n- To: {data['dstToken']['symbol']}\n- Input: {int(data['srcAmount']) \u002F 10**data['srcToken']['decimals']:.6f}\n- Output: {int(data['dstAmount']) \u002F 10**data['dstToken']['decimals']:.6f}\n- Gas: {data.get('gas', 'N\u002FA')}\n\"\"\"\n```\n\n## CoW Protocol Integration\n\n### MEV-Protected Swaps\n\n```python\n# scripts\u002Fcow_swap.py\nimport aiohttp\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\nfrom eth_account import Account\nfrom eth_account.messages import encode_typed_data\n\nCOW_API = {\n    \"ethereum\": \"https:\u002F\u002Fapi.cow.fi\u002Fmainnet\",\n    \"gnosis\": \"https:\u002F\u002Fapi.cow.fi\u002Fxdai\"\n}\n\nclass CowSwapTool(BaseTool):\n    name: str = \"cow_swap\"\n    description: str = \"MEV-protected swaps via CoW Protocol\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"action\": {\"type\": \"string\", \"enum\": [\"quote\", \"order\"]},\n            \"sell_token\": {\"type\": \"string\"},\n            \"buy_token\": {\"type\": \"string\"},\n            \"sell_amount\": {\"type\": \"string\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"ethereum\"}\n        },\n        \"required\": [\"action\", \"sell_token\", \"buy_token\", \"sell_amount\"]\n    })\n\n    async def execute(self, action: str, sell_token: str, buy_token: str,\n                      sell_amount: str, chain: str = \"ethereum\") -> str:\n        base_url = COW_API[chain]\n\n        if action == \"quote\":\n            return await self._get_quote(base_url, sell_token, buy_token, sell_amount)\n        else:\n            return await self._create_order(base_url, sell_token, buy_token, sell_amount)\n\n    async def _get_quote(self, base_url: str, sell_token: str,\n                         buy_token: str, sell_amount: str) -> str:\n        url = f\"{base_url}\u002Fapi\u002Fv1\u002Fquote\"\n\n        payload = {\n            \"sellToken\": sell_token,\n            \"buyToken\": buy_token,\n            \"sellAmountBeforeFee\": sell_amount,\n            \"kind\": \"sell\",\n            \"from\": os.getenv(\"WALLET_ADDRESS\"),\n            \"receiver\": os.getenv(\"WALLET_ADDRESS\")\n        }\n\n        async with aiohttp.ClientSession() as session:\n            async with session.post(url, json=payload) as resp:\n                if resp.status != 200:\n                    return f\"Error: {await resp.text()}\"\n\n                data = await resp.json()\n                return f\"\"\"\nCoW Protocol Quote:\n- Sell: {int(data['quote']['sellAmount']) \u002F 1e18:.6f}\n- Buy: {int(data['quote']['buyAmount']) \u002F 1e18:.6f}\n- Fee: {int(data['quote']['feeAmount']) \u002F 1e18:.6f}\n- Valid until: {data['quote']['validTo']}\n- MEV Protected: Yes\n\"\"\"\n```\n\n## Yield Strategy Tools\n\n### APY Aggregator\n\n```python\n# scripts\u002Fyield_finder.py\nimport aiohttp\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\n\nDEFI_LLAMA_API = \"https:\u002F\u002Fyields.llama.fi\"\n\nclass YieldFinderTool(BaseTool):\n    name: str = \"yield_finder\"\n    description: str = \"Find best DeFi yields across protocols\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"token\": {\"type\": \"string\", \"description\": \"Token symbol\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"all\"},\n            \"min_tvl\": {\"type\": \"number\", \"default\": 1000000},\n            \"top_n\": {\"type\": \"integer\", \"default\": 5}\n        },\n        \"required\": [\"token\"]\n    })\n\n    async def execute(self, token: str, chain: str = \"all\",\n                      min_tvl: float = 1000000, top_n: int = 5) -> str:\n        async with aiohttp.ClientSession() as session:\n            async with session.get(f\"{DEFI_LLAMA_API}\u002Fpools\") as resp:\n                if resp.status != 200:\n                    return f\"Error fetching yields\"\n\n                pools = await resp.json()\n\n        # Filter by token and criteria\n        filtered = [\n            p for p in pools[\"data\"]\n            if token.upper() in p.get(\"symbol\", \"\").upper()\n            and p.get(\"tvlUsd\", 0) >= min_tvl\n            and (chain == \"all\" or p.get(\"chain\", \"\").lower() == chain.lower())\n        ]\n\n        # Sort by APY\n        filtered.sort(key=lambda x: x.get(\"apy\", 0), reverse=True)\n\n        result = f\"Top {top_n} yields for {token}:\\n\\n\"\n        for i, pool in enumerate(filtered[:top_n], 1):\n            result += f\"\"\"{i}. {pool['project']} ({pool['chain']})\n   - APY: {pool['apy']:.2f}%\n   - TVL: ${pool['tvlUsd']:,.0f}\n   - Pool: {pool['symbol']}\n\n\"\"\"\n\n        return result\n```\n\n## Token Addresses\n\n### Common Tokens\n\n```python\nTOKENS = {\n    \"ethereum\": {\n        \"USDC\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        \"USDT\": \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n        \"DAI\": \"0x6B175474E89094C44Da98b954EeacdeCB5BE3830\",\n        \"WETH\": \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n        \"WBTC\": \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\",\n        \"AAVE\": \"0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9\"\n    },\n    \"polygon\": {\n        \"USDC\": \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",  # Native USDC\n        \"USDT\": \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n        \"WETH\": \"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619\",\n        \"WPOL\": \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\"\n    },\n    \"arbitrum\": {\n        \"USDC\": \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",  # Native\n        \"USDT\": \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n        \"WETH\": \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\",\n        \"ARB\": \"0x912CE59144191C1204E64559FE8253a0e49E6548\"\n    },\n    \"base\": {\n        \"USDC\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        \"WETH\": \"0x4200000000000000000000000000000000000006\",\n        \"cbETH\": \"0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22\"\n    }\n}\n```\n\n## Environment Variables\n\n```bash\n# API Keys\nONEINCH_API_KEY=...\n\n# RPC URLs\nETHEREUM_RPC=https:\u002F\u002Feth.llamarpc.com\nPOLYGON_RPC=https:\u002F\u002Fpolygon-rpc.com\nARBITRUM_RPC=https:\u002F\u002Farb1.arbitrum.io\u002Frpc\n\n# Wallet\nPRIVATE_KEY=0x...\nWALLET_ADDRESS=0x...\n```\n\n## References\n\n- `references\u002Faave-abi.md` - Aave V3 contract ABIs\n- `references\u002Fdefi-addresses.md` - Protocol addresses by chain\n- `references\u002Ftoken-lists.md` - Verified token addresses\n","# DeFi Protocol Integration\n\nConnect SpoonOS agents to major DeFi protocols.\n\n## Supported Protocols\n\n| Protocol | Type | Chains |\n|----------|------|--------|\n| Aave V3 | Lending | ETH, Polygon, Arbitrum, Optimism, Base |\n| Compound V3 | Lending | ETH, Polygon, Arbitrum, Base |\n| 1inch | DEX Aggregator | All major EVM |\n| CoW Protocol | MEV-protected swaps | ETH, Gnosis |\n| Uniswap V3 | DEX | All major EVM |\n\n## Aave V3 Integration\n\n### Contract Addresses\n\n```python\nAAVE_V3_ADDRESSES = {\n    \"ethereum\": {\n        \"pool\": \"0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2\",\n        \"pool_data_provider\": \"0x7B4EB56E7CD4b454BA8ff71E4518426369a138a3\",\n        \"oracle\": \"0x54586bE62E3c3580375aE3723C145253060Ca0C2\"\n    },\n    \"polygon\": {\n        \"pool\": \"0x794a61358D6845594F94dc1DB02A252b5b4814aD\",\n        \"pool_data_provider\": \"0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654\",\n        \"oracle\": \"0xb023e699F5a33916Ea823A16485e259257cA8Bd1\"\n    },\n    \"arbitrum\": {\n        \"pool\": \"0x794a61358D6845594F94dc1DB02A252b5b4814aD\",\n        \"pool_data_provider\": \"0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654\",\n        \"oracle\": \"0xb56c2F0B653B2e0b10C9b928C8580Ac5Df02C7C7\"\n    },\n    \"base\": {\n        \"pool\": \"0xA238Dd80C259a72e81d7e4664a9801593F98d1c5\",\n        \"pool_data_provider\": \"0x2d8A3C5677189723C4cB8873CfC9C8976FDF38Ac\",\n        \"oracle\": \"0x2Cc0Fc26eD4563A5ce5e8bdcfe1A2878676Ae156\"\n    }\n}\n```\n\n### Aave Tool Implementation\n\n```python\n# scripts\u002Faave_lending.py\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\nfrom web3 import Web3\nimport json\n\nAAVE_POOL_ABI = [...]  # See references\u002Faave-abi.md\n\nclass AaveLendingTool(BaseTool):\n    name: str = \"aave_lending\"\n    description: str = \"Supply, borrow, repay on Aave V3\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"action\": {\n                \"type\": \"string\",\n                \"enum\": [\"supply\", \"borrow\", \"repay\", \"withdraw\", \"positions\"],\n                \"description\": \"Lending action to perform\"\n            },\n            \"asset\": {\"type\": \"string\", \"description\": \"Token symbol (USDC, WETH, etc.)\"},\n            \"amount\": {\"type\": \"string\", \"description\": \"Amount in token units\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"ethereum\"}\n        },\n        \"required\": [\"action\"]\n    })\n\n    async def execute(self, action: str, asset: str = None,\n                      amount: str = None, chain: str = \"ethereum\") -> str:\n        if action == \"positions\":\n            return await self._get_positions(chain)\n        elif action == \"supply\":\n            return await self._supply(asset, amount, chain)\n        elif action == \"borrow\":\n            return await self._borrow(asset, amount, chain)\n        elif action == \"repay\":\n            return await self._repay(asset, amount, chain)\n        elif action == \"withdraw\":\n            return await self._withdraw(asset, amount, chain)\n\n    async def _get_positions(self, chain: str) -> str:\n        \"\"\"Get user's Aave positions.\"\"\"\n        addresses = AAVE_V3_ADDRESSES[chain]\n        w3 = Web3(Web3.HTTPProvider(RPC_URLS[chain]))\n\n        pool_data = w3.eth.contract(\n            address=addresses[\"pool_data_provider\"],\n            abi=POOL_DATA_PROVIDER_ABI\n        )\n\n        user_address = os.getenv(\"WALLET_ADDRESS\")\n        reserves = pool_data.functions.getUserReservesData(\n            addresses[\"pool\"],\n            user_address\n        ).call()\n\n        positions = []\n        for reserve in reserves:\n            if reserve[1] > 0 or reserve[2] > 0:  # supplied or borrowed\n                positions.append({\n                    \"asset\": reserve[0],\n                    \"supplied\": reserve[1] \u002F 1e18,\n                    \"borrowed\": reserve[2] \u002F 1e18\n                })\n\n        return json.dumps({\"positions\": positions}, indent=2)\n```\n\n## 1inch Integration\n\n### API Configuration\n\n```python\nONEINCH_API = {\n    \"base_url\": \"https:\u002F\u002Fapi.1inch.dev\",\n    \"swap_endpoint\": \"\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fswap\",\n    \"quote_endpoint\": \"\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fquote\",\n    \"tokens_endpoint\": \"\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Ftokens\"\n}\n\nCHAIN_IDS = {\n    \"ethereum\": 1,\n    \"polygon\": 137,\n    \"arbitrum\": 42161,\n    \"optimism\": 10,\n    \"base\": 8453\n}\n```\n\n### 1inch Swap Tool\n\n```python\n# scripts\u002Foneinch_swap.py\nimport aiohttp\nimport os\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\n\nclass OneInchSwapTool(BaseTool):\n    name: str = \"oneinch_swap\"\n    description: str = \"Get swap quotes and execute via 1inch aggregator\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"action\": {\"type\": \"string\", \"enum\": [\"quote\", \"swap\"]},\n            \"from_token\": {\"type\": \"string\", \"description\": \"Source token address\"},\n            \"to_token\": {\"type\": \"string\", \"description\": \"Destination token address\"},\n            \"amount\": {\"type\": \"string\", \"description\": \"Amount in wei\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"ethereum\"},\n            \"slippage\": {\"type\": \"number\", \"default\": 1, \"description\": \"Slippage %\"}\n        },\n        \"required\": [\"action\", \"from_token\", \"to_token\", \"amount\"]\n    })\n\n    async def execute(self, action: str, from_token: str, to_token: str,\n                      amount: str, chain: str = \"ethereum\", slippage: float = 1) -> str:\n        chain_id = CHAIN_IDS[chain]\n        api_key = os.getenv(\"ONEINCH_API_KEY\")\n\n        headers = {\n            \"Authorization\": f\"Bearer {api_key}\",\n            \"Content-Type\": \"application\u002Fjson\"\n        }\n\n        if action == \"quote\":\n            url = f\"{ONEINCH_API['base_url']}\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fquote\"\n            params = {\n                \"src\": from_token,\n                \"dst\": to_token,\n                \"amount\": amount\n            }\n        else:\n            url = f\"{ONEINCH_API['base_url']}\u002Fswap\u002Fv6.0\u002F{chain_id}\u002Fswap\"\n            params = {\n                \"src\": from_token,\n                \"dst\": to_token,\n                \"amount\": amount,\n                \"from\": os.getenv(\"WALLET_ADDRESS\"),\n                \"slippage\": slippage\n            }\n\n        async with aiohttp.ClientSession() as session:\n            async with session.get(url, headers=headers, params=params) as resp:\n                if resp.status != 200:\n                    error = await resp.text()\n                    return f\"Error: {error}\"\n\n                data = await resp.json()\n\n                if action == \"quote\":\n                    return self._format_quote(data)\n                else:\n                    return self._format_swap(data)\n\n    def _format_quote(self, data: dict) -> str:\n        return f\"\"\"\n1inch Quote:\n- From: {data['srcToken']['symbol']}\n- To: {data['dstToken']['symbol']}\n- Input: {int(data['srcAmount']) \u002F 10**data['srcToken']['decimals']:.6f}\n- Output: {int(data['dstAmount']) \u002F 10**data['dstToken']['decimals']:.6f}\n- Gas: {data.get('gas', 'N\u002FA')}\n\"\"\"\n```\n\n## CoW Protocol Integration\n\n### MEV-Protected Swaps\n\n```python\n# scripts\u002Fcow_swap.py\nimport aiohttp\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\nfrom eth_account import Account\nfrom eth_account.messages import encode_typed_data\n\nCOW_API = {\n    \"ethereum\": \"https:\u002F\u002Fapi.cow.fi\u002Fmainnet\",\n    \"gnosis\": \"https:\u002F\u002Fapi.cow.fi\u002Fxdai\"\n}\n\nclass CowSwapTool(BaseTool):\n    name: str = \"cow_swap\"\n    description: str = \"MEV-protected swaps via CoW Protocol\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"action\": {\"type\": \"string\", \"enum\": [\"quote\", \"order\"]},\n            \"sell_token\": {\"type\": \"string\"},\n            \"buy_token\": {\"type\": \"string\"},\n            \"sell_amount\": {\"type\": \"string\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"ethereum\"}\n        },\n        \"required\": [\"action\", \"sell_token\", \"buy_token\", \"sell_amount\"]\n    })\n\n    async def execute(self, action: str, sell_token: str, buy_token: str,\n                      sell_amount: str, chain: str = \"ethereum\") -> str:\n        base_url = COW_API[chain]\n\n        if action == \"quote\":\n            return await self._get_quote(base_url, sell_token, buy_token, sell_amount)\n        else:\n            return await self._create_order(base_url, sell_token, buy_token, sell_amount)\n\n    async def _get_quote(self, base_url: str, sell_token: str,\n                         buy_token: str, sell_amount: str) -> str:\n        url = f\"{base_url}\u002Fapi\u002Fv1\u002Fquote\"\n\n        payload = {\n            \"sellToken\": sell_token,\n            \"buyToken\": buy_token,\n            \"sellAmountBeforeFee\": sell_amount,\n            \"kind\": \"sell\",\n            \"from\": os.getenv(\"WALLET_ADDRESS\"),\n            \"receiver\": os.getenv(\"WALLET_ADDRESS\")\n        }\n\n        async with aiohttp.ClientSession() as session:\n            async with session.post(url, json=payload) as resp:\n                if resp.status != 200:\n                    return f\"Error: {await resp.text()}\"\n\n                data = await resp.json()\n                return f\"\"\"\nCoW Protocol Quote:\n- Sell: {int(data['quote']['sellAmount']) \u002F 1e18:.6f}\n- Buy: {int(data['quote']['buyAmount']) \u002F 1e18:.6f}\n- Fee: {int(data['quote']['feeAmount']) \u002F 1e18:.6f}\n- Valid until: {data['quote']['validTo']}\n- MEV Protected: Yes\n\"\"\"\n```\n\n## Yield Strategy Tools\n\n### APY Aggregator\n\n```python\n# scripts\u002Fyield_finder.py\nimport aiohttp\nfrom spoon_ai.tools.base import BaseTool\nfrom pydantic import Field\n\nDEFI_LLAMA_API = \"https:\u002F\u002Fyields.llama.fi\"\n\nclass YieldFinderTool(BaseTool):\n    name: str = \"yield_finder\"\n    description: str = \"Find best DeFi yields across protocols\"\n    parameters: dict = Field(default={\n        \"type\": \"object\",\n        \"properties\": {\n            \"token\": {\"type\": \"string\", \"description\": \"Token symbol\"},\n            \"chain\": {\"type\": \"string\", \"default\": \"all\"},\n            \"min_tvl\": {\"type\": \"number\", \"default\": 1000000},\n            \"top_n\": {\"type\": \"integer\", \"default\": 5}\n        },\n        \"required\": [\"token\"]\n    })\n\n    async def execute(self, token: str, chain: str = \"all\",\n                      min_tvl: float = 1000000, top_n: int = 5) -> str:\n        async with aiohttp.ClientSession() as session:\n            async with session.get(f\"{DEFI_LLAMA_API}\u002Fpools\") as resp:\n                if resp.status != 200:\n                    return f\"Error fetching yields\"\n\n                pools = await resp.json()\n\n        # Filter by token and criteria\n        filtered = [\n            p for p in pools[\"data\"]\n            if token.upper() in p.get(\"symbol\", \"\").upper()\n            and p.get(\"tvlUsd\", 0) >= min_tvl\n            and (chain == \"all\" or p.get(\"chain\", \"\").lower() == chain.lower())\n        ]\n\n        # Sort by APY\n        filtered.sort(key=lambda x: x.get(\"apy\", 0), reverse=True)\n\n        result = f\"Top {top_n} yields for {token}:\\n\\n\"\n        for i, pool in enumerate(filtered[:top_n], 1):\n            result += f\"\"\"{i}. {pool['project']} ({pool['chain']})\n   - APY: {pool['apy']:.2f}%\n   - TVL: ${pool['tvlUsd']:,.0f}\n   - Pool: {pool['symbol']}\n\n\"\"\"\n\n        return result\n```\n\n## Token Addresses\n\n### Common Tokens\n\n```python\nTOKENS = {\n    \"ethereum\": {\n        \"USDC\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        \"USDT\": \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n        \"DAI\": \"0x6B175474E89094C44Da98b954EeacdeCB5BE3830\",\n        \"WETH\": \"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\",\n        \"WBTC\": \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\",\n        \"AAVE\": \"0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9\"\n    },\n    \"polygon\": {\n        \"USDC\": \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",  # Native USDC\n        \"USDT\": \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n        \"WETH\": \"0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619\",\n        \"WPOL\": \"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270\"\n    },\n    \"arbitrum\": {\n        \"USDC\": \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",  # Native\n        \"USDT\": \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n        \"WETH\": \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\",\n        \"ARB\": \"0x912CE59144191C1204E64559FE8253a0e49E6548\"\n    },\n    \"base\": {\n        \"USDC\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        \"WETH\": \"0x4200000000000000000000000000000000000006\",\n        \"cbETH\": \"0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22\"\n    }\n}\n```\n\n## Environment Variables\n\n```bash\n# API Keys\nONEINCH_API_KEY=...\n\n# RPC URLs\nETHEREUM_RPC=https:\u002F\u002Feth.llamarpc.com\nPOLYGON_RPC=https:\u002F\u002Fpolygon-rpc.com\nARBITRUM_RPC=https:\u002F\u002Farb1.arbitrum.io\u002Frpc\n\n# Wallet\nPRIVATE_KEY=0x...\nWALLET_ADDRESS=0x...\n```\n\n## References\n\n- `references\u002Faave-abi.md` - Aave V3 contract ABIs\n- `references\u002Fdefi-addresses.md` - Protocol addresses by chain\n- `references\u002Ftoken-lists.md` - Verified token addresses\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-11 08:47:40",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill web3-defi-protocols",{"tool":57,"command":58},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill web3-defi-protocols",{"tool":60,"command":61},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill web3-defi-protocols","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002FSKILL.md",true,[65,71,75,79,83,89],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"scripts\u002Faave_lending.py","SCRIPT","脚本",3884,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002Fscripts\u002Faave_lending.py",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"scripts\u002Fcow_swap.py",3068,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002Fscripts\u002Fcow_swap.py",{"path":76,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":77,"sourceHtmlUrl":78},"scripts\u002Foneinch_swap.py",3603,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002Fscripts\u002Foneinch_swap.py",{"path":80,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":81,"sourceHtmlUrl":82},"scripts\u002Fyield_finder.py",2261,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002Fscripts\u002Fyield_finder.py",{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"SOURCE.md","REFERENCE","参考文档",371,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002FSOURCE.md",{"path":90,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":91,"sourceHtmlUrl":92},"TRUST.auto.yaml",2176,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fai-crypto\u002Fxspoonai-official-web3-defi-protocols\u002FTRUST.auto.yaml",[94,123,146,164,177,187],{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":98,"licenseFileUrl":99,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":37},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":128,"sourceHtmlUrl":129,"categories":130,"keywords":131,"publishedAt":37},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[132,133,134,135,136,137,138,139,140,141,142,143,144,145],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":150,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":37},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[154,133,155,156,157,158,159,143,142,141,160,161,162,137,163,136,135],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":165,"name":166,"nameZh":6,"description":167,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":168,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":37},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[172,173,134,174,175,144,142,176,140,139,137,136],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":178,"name":179,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":98,"licenseFileUrl":180,"sourceHtmlUrl":181,"categories":182,"keywords":183,"publishedAt":37},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[184,185,186],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":98,"licenseFileUrl":191,"sourceHtmlUrl":192,"categories":193,"keywords":194,"publishedAt":37},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[195,196,197,198,199,200,201,34,202,203,204],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]