intentkit 0.5.0__py3-none-any.whl → 0.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of intentkit might be problematic. Click here for more details.
- intentkit/__init__.py +17 -0
- intentkit/abstracts/__init__.py +0 -0
- intentkit/abstracts/agent.py +60 -0
- intentkit/abstracts/api.py +4 -0
- intentkit/abstracts/engine.py +38 -0
- intentkit/abstracts/exception.py +9 -0
- intentkit/abstracts/graph.py +25 -0
- intentkit/abstracts/skill.py +129 -0
- intentkit/abstracts/twitter.py +54 -0
- intentkit/clients/__init__.py +14 -0
- intentkit/clients/cdp.py +53 -0
- intentkit/clients/twitter.py +445 -0
- intentkit/config/__init__.py +0 -0
- intentkit/config/config.py +164 -0
- intentkit/core/__init__.py +0 -0
- intentkit/core/agent.py +191 -0
- intentkit/core/api.py +40 -0
- intentkit/core/client.py +45 -0
- intentkit/core/credit.py +1767 -0
- intentkit/core/engine.py +1018 -0
- intentkit/core/node.py +223 -0
- intentkit/core/prompt.py +58 -0
- intentkit/core/skill.py +124 -0
- intentkit/models/agent.py +1689 -0
- intentkit/models/agent_data.py +810 -0
- intentkit/models/agent_schema.json +733 -0
- intentkit/models/app_setting.py +156 -0
- intentkit/models/base.py +9 -0
- intentkit/models/chat.py +581 -0
- intentkit/models/conversation.py +286 -0
- intentkit/models/credit.py +1406 -0
- intentkit/models/db.py +120 -0
- intentkit/models/db_mig.py +102 -0
- intentkit/models/generator.py +347 -0
- intentkit/models/llm.py +746 -0
- intentkit/models/redis.py +132 -0
- intentkit/models/skill.py +466 -0
- intentkit/models/user.py +243 -0
- intentkit/skills/__init__.py +12 -0
- intentkit/skills/acolyt/__init__.py +83 -0
- intentkit/skills/acolyt/acolyt.jpg +0 -0
- intentkit/skills/acolyt/ask.py +128 -0
- intentkit/skills/acolyt/base.py +28 -0
- intentkit/skills/acolyt/schema.json +89 -0
- intentkit/skills/aixbt/README.md +71 -0
- intentkit/skills/aixbt/__init__.py +73 -0
- intentkit/skills/aixbt/aixbt.jpg +0 -0
- intentkit/skills/aixbt/base.py +21 -0
- intentkit/skills/aixbt/projects.py +153 -0
- intentkit/skills/aixbt/schema.json +99 -0
- intentkit/skills/allora/__init__.py +83 -0
- intentkit/skills/allora/allora.jpeg +0 -0
- intentkit/skills/allora/base.py +28 -0
- intentkit/skills/allora/price.py +130 -0
- intentkit/skills/allora/schema.json +89 -0
- intentkit/skills/base.py +174 -0
- intentkit/skills/carv/README.md +95 -0
- intentkit/skills/carv/__init__.py +121 -0
- intentkit/skills/carv/base.py +183 -0
- intentkit/skills/carv/carv.webp +0 -0
- intentkit/skills/carv/fetch_news.py +92 -0
- intentkit/skills/carv/onchain_query.py +164 -0
- intentkit/skills/carv/schema.json +137 -0
- intentkit/skills/carv/token_info_and_price.py +110 -0
- intentkit/skills/cdp/__init__.py +137 -0
- intentkit/skills/cdp/base.py +21 -0
- intentkit/skills/cdp/cdp.png +0 -0
- intentkit/skills/cdp/get_balance.py +81 -0
- intentkit/skills/cdp/schema.json +473 -0
- intentkit/skills/chainlist/README.md +38 -0
- intentkit/skills/chainlist/__init__.py +54 -0
- intentkit/skills/chainlist/base.py +21 -0
- intentkit/skills/chainlist/chain_lookup.py +208 -0
- intentkit/skills/chainlist/chainlist.png +0 -0
- intentkit/skills/chainlist/schema.json +47 -0
- intentkit/skills/common/__init__.py +82 -0
- intentkit/skills/common/base.py +21 -0
- intentkit/skills/common/common.jpg +0 -0
- intentkit/skills/common/current_time.py +84 -0
- intentkit/skills/common/schema.json +57 -0
- intentkit/skills/cookiefun/README.md +121 -0
- intentkit/skills/cookiefun/__init__.py +78 -0
- intentkit/skills/cookiefun/base.py +41 -0
- intentkit/skills/cookiefun/constants.py +18 -0
- intentkit/skills/cookiefun/cookiefun.png +0 -0
- intentkit/skills/cookiefun/get_account_details.py +171 -0
- intentkit/skills/cookiefun/get_account_feed.py +282 -0
- intentkit/skills/cookiefun/get_account_smart_followers.py +181 -0
- intentkit/skills/cookiefun/get_sectors.py +128 -0
- intentkit/skills/cookiefun/schema.json +155 -0
- intentkit/skills/cookiefun/search_accounts.py +225 -0
- intentkit/skills/cryptocompare/__init__.py +130 -0
- intentkit/skills/cryptocompare/api.py +159 -0
- intentkit/skills/cryptocompare/base.py +303 -0
- intentkit/skills/cryptocompare/cryptocompare.png +0 -0
- intentkit/skills/cryptocompare/fetch_news.py +96 -0
- intentkit/skills/cryptocompare/fetch_price.py +99 -0
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +113 -0
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +109 -0
- intentkit/skills/cryptocompare/fetch_top_volume.py +108 -0
- intentkit/skills/cryptocompare/fetch_trading_signals.py +107 -0
- intentkit/skills/cryptocompare/schema.json +168 -0
- intentkit/skills/cryptopanic/__init__.py +108 -0
- intentkit/skills/cryptopanic/base.py +51 -0
- intentkit/skills/cryptopanic/cryptopanic.png +0 -0
- intentkit/skills/cryptopanic/fetch_crypto_news.py +153 -0
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +136 -0
- intentkit/skills/cryptopanic/schema.json +103 -0
- intentkit/skills/dapplooker/README.md +92 -0
- intentkit/skills/dapplooker/__init__.py +83 -0
- intentkit/skills/dapplooker/base.py +26 -0
- intentkit/skills/dapplooker/dapplooker.jpg +0 -0
- intentkit/skills/dapplooker/dapplooker_token_data.py +476 -0
- intentkit/skills/dapplooker/schema.json +91 -0
- intentkit/skills/defillama/__init__.py +323 -0
- intentkit/skills/defillama/api.py +315 -0
- intentkit/skills/defillama/base.py +135 -0
- intentkit/skills/defillama/coins/__init__.py +0 -0
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +116 -0
- intentkit/skills/defillama/coins/fetch_block.py +98 -0
- intentkit/skills/defillama/coins/fetch_current_prices.py +105 -0
- intentkit/skills/defillama/coins/fetch_first_price.py +100 -0
- intentkit/skills/defillama/coins/fetch_historical_prices.py +110 -0
- intentkit/skills/defillama/coins/fetch_price_chart.py +109 -0
- intentkit/skills/defillama/coins/fetch_price_percentage.py +93 -0
- intentkit/skills/defillama/config/__init__.py +0 -0
- intentkit/skills/defillama/config/chains.py +433 -0
- intentkit/skills/defillama/defillama.jpeg +0 -0
- intentkit/skills/defillama/fees/__init__.py +0 -0
- intentkit/skills/defillama/fees/fetch_fees_overview.py +130 -0
- intentkit/skills/defillama/schema.json +383 -0
- intentkit/skills/defillama/stablecoins/__init__.py +0 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +100 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +129 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +83 -0
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +126 -0
- intentkit/skills/defillama/tests/__init__.py +0 -0
- intentkit/skills/defillama/tests/api_integration.test.py +192 -0
- intentkit/skills/defillama/tests/api_unit.test.py +583 -0
- intentkit/skills/defillama/tvl/__init__.py +0 -0
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +106 -0
- intentkit/skills/defillama/tvl/fetch_chains.py +107 -0
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +91 -0
- intentkit/skills/defillama/tvl/fetch_protocol.py +207 -0
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +93 -0
- intentkit/skills/defillama/tvl/fetch_protocols.py +196 -0
- intentkit/skills/defillama/volumes/__init__.py +0 -0
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +157 -0
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +123 -0
- intentkit/skills/defillama/volumes/fetch_options_overview.py +131 -0
- intentkit/skills/defillama/yields/__init__.py +0 -0
- intentkit/skills/defillama/yields/fetch_pool_chart.py +100 -0
- intentkit/skills/defillama/yields/fetch_pools.py +126 -0
- intentkit/skills/dexscreener/__init__.py +93 -0
- intentkit/skills/dexscreener/base.py +133 -0
- intentkit/skills/dexscreener/dexscreener.png +0 -0
- intentkit/skills/dexscreener/model/__init__.py +0 -0
- intentkit/skills/dexscreener/model/search_token_response.py +82 -0
- intentkit/skills/dexscreener/schema.json +48 -0
- intentkit/skills/dexscreener/search_token.py +321 -0
- intentkit/skills/dune_analytics/__init__.py +103 -0
- intentkit/skills/dune_analytics/base.py +46 -0
- intentkit/skills/dune_analytics/dune.png +0 -0
- intentkit/skills/dune_analytics/fetch_kol_buys.py +128 -0
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +237 -0
- intentkit/skills/dune_analytics/schema.json +99 -0
- intentkit/skills/elfa/README.md +100 -0
- intentkit/skills/elfa/__init__.py +123 -0
- intentkit/skills/elfa/base.py +28 -0
- intentkit/skills/elfa/elfa.jpg +0 -0
- intentkit/skills/elfa/mention.py +504 -0
- intentkit/skills/elfa/schema.json +153 -0
- intentkit/skills/elfa/stats.py +118 -0
- intentkit/skills/elfa/tokens.py +126 -0
- intentkit/skills/enso/README.md +75 -0
- intentkit/skills/enso/__init__.py +114 -0
- intentkit/skills/enso/abi/__init__.py +0 -0
- intentkit/skills/enso/abi/approval.py +279 -0
- intentkit/skills/enso/abi/erc20.py +14 -0
- intentkit/skills/enso/abi/route.py +129 -0
- intentkit/skills/enso/base.py +44 -0
- intentkit/skills/enso/best_yield.py +286 -0
- intentkit/skills/enso/enso.jpg +0 -0
- intentkit/skills/enso/networks.py +105 -0
- intentkit/skills/enso/prices.py +93 -0
- intentkit/skills/enso/route.py +300 -0
- intentkit/skills/enso/schema.json +212 -0
- intentkit/skills/enso/tokens.py +223 -0
- intentkit/skills/enso/wallet.py +381 -0
- intentkit/skills/github/README.md +63 -0
- intentkit/skills/github/__init__.py +54 -0
- intentkit/skills/github/base.py +21 -0
- intentkit/skills/github/github.jpg +0 -0
- intentkit/skills/github/github_search.py +183 -0
- intentkit/skills/github/schema.json +59 -0
- intentkit/skills/heurist/__init__.py +143 -0
- intentkit/skills/heurist/base.py +26 -0
- intentkit/skills/heurist/heurist.png +0 -0
- intentkit/skills/heurist/image_generation_animagine_xl.py +162 -0
- intentkit/skills/heurist/image_generation_arthemy_comics.py +162 -0
- intentkit/skills/heurist/image_generation_arthemy_real.py +162 -0
- intentkit/skills/heurist/image_generation_braindance.py +162 -0
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +162 -0
- intentkit/skills/heurist/image_generation_flux_1_dev.py +162 -0
- intentkit/skills/heurist/image_generation_sdxl.py +161 -0
- intentkit/skills/heurist/schema.json +196 -0
- intentkit/skills/lifi/README.md +294 -0
- intentkit/skills/lifi/__init__.py +141 -0
- intentkit/skills/lifi/base.py +21 -0
- intentkit/skills/lifi/lifi.png +0 -0
- intentkit/skills/lifi/schema.json +89 -0
- intentkit/skills/lifi/token_execute.py +472 -0
- intentkit/skills/lifi/token_quote.py +190 -0
- intentkit/skills/lifi/utils.py +656 -0
- intentkit/skills/moralis/README.md +490 -0
- intentkit/skills/moralis/__init__.py +110 -0
- intentkit/skills/moralis/api.py +281 -0
- intentkit/skills/moralis/base.py +55 -0
- intentkit/skills/moralis/fetch_chain_portfolio.py +191 -0
- intentkit/skills/moralis/fetch_nft_portfolio.py +284 -0
- intentkit/skills/moralis/fetch_solana_portfolio.py +331 -0
- intentkit/skills/moralis/fetch_wallet_portfolio.py +301 -0
- intentkit/skills/moralis/moralis.png +0 -0
- intentkit/skills/moralis/schema.json +156 -0
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +511 -0
- intentkit/skills/nation/__init__.py +62 -0
- intentkit/skills/nation/base.py +31 -0
- intentkit/skills/nation/nation.png +0 -0
- intentkit/skills/nation/nft_check.py +106 -0
- intentkit/skills/nation/schema.json +58 -0
- intentkit/skills/openai/__init__.py +107 -0
- intentkit/skills/openai/base.py +32 -0
- intentkit/skills/openai/dalle_image_generation.py +128 -0
- intentkit/skills/openai/gpt_image_generation.py +152 -0
- intentkit/skills/openai/gpt_image_to_image.py +186 -0
- intentkit/skills/openai/image_to_text.py +126 -0
- intentkit/skills/openai/openai.png +0 -0
- intentkit/skills/openai/schema.json +139 -0
- intentkit/skills/portfolio/README.md +55 -0
- intentkit/skills/portfolio/__init__.py +151 -0
- intentkit/skills/portfolio/base.py +107 -0
- intentkit/skills/portfolio/constants.py +9 -0
- intentkit/skills/portfolio/moralis.png +0 -0
- intentkit/skills/portfolio/schema.json +237 -0
- intentkit/skills/portfolio/token_balances.py +155 -0
- intentkit/skills/portfolio/wallet_approvals.py +102 -0
- intentkit/skills/portfolio/wallet_defi_positions.py +80 -0
- intentkit/skills/portfolio/wallet_history.py +155 -0
- intentkit/skills/portfolio/wallet_net_worth.py +112 -0
- intentkit/skills/portfolio/wallet_nfts.py +139 -0
- intentkit/skills/portfolio/wallet_profitability.py +101 -0
- intentkit/skills/portfolio/wallet_profitability_summary.py +91 -0
- intentkit/skills/portfolio/wallet_stats.py +79 -0
- intentkit/skills/portfolio/wallet_swaps.py +147 -0
- intentkit/skills/skills.toml +103 -0
- intentkit/skills/slack/__init__.py +98 -0
- intentkit/skills/slack/base.py +55 -0
- intentkit/skills/slack/get_channel.py +109 -0
- intentkit/skills/slack/get_message.py +136 -0
- intentkit/skills/slack/schedule_message.py +92 -0
- intentkit/skills/slack/schema.json +135 -0
- intentkit/skills/slack/send_message.py +81 -0
- intentkit/skills/slack/slack.jpg +0 -0
- intentkit/skills/system/__init__.py +90 -0
- intentkit/skills/system/base.py +22 -0
- intentkit/skills/system/read_agent_api_key.py +87 -0
- intentkit/skills/system/regenerate_agent_api_key.py +77 -0
- intentkit/skills/system/schema.json +53 -0
- intentkit/skills/system/system.svg +76 -0
- intentkit/skills/tavily/README.md +86 -0
- intentkit/skills/tavily/__init__.py +91 -0
- intentkit/skills/tavily/base.py +27 -0
- intentkit/skills/tavily/schema.json +119 -0
- intentkit/skills/tavily/tavily.jpg +0 -0
- intentkit/skills/tavily/tavily_extract.py +147 -0
- intentkit/skills/tavily/tavily_search.py +139 -0
- intentkit/skills/token/README.md +89 -0
- intentkit/skills/token/__init__.py +107 -0
- intentkit/skills/token/base.py +154 -0
- intentkit/skills/token/constants.py +9 -0
- intentkit/skills/token/erc20_transfers.py +145 -0
- intentkit/skills/token/moralis.png +0 -0
- intentkit/skills/token/schema.json +141 -0
- intentkit/skills/token/token_analytics.py +81 -0
- intentkit/skills/token/token_price.py +132 -0
- intentkit/skills/token/token_search.py +121 -0
- intentkit/skills/twitter/__init__.py +146 -0
- intentkit/skills/twitter/base.py +68 -0
- intentkit/skills/twitter/follow_user.py +69 -0
- intentkit/skills/twitter/get_mentions.py +124 -0
- intentkit/skills/twitter/get_timeline.py +111 -0
- intentkit/skills/twitter/get_user_by_username.py +84 -0
- intentkit/skills/twitter/get_user_tweets.py +123 -0
- intentkit/skills/twitter/like_tweet.py +65 -0
- intentkit/skills/twitter/post_tweet.py +90 -0
- intentkit/skills/twitter/reply_tweet.py +98 -0
- intentkit/skills/twitter/retweet.py +76 -0
- intentkit/skills/twitter/schema.json +258 -0
- intentkit/skills/twitter/search_tweets.py +115 -0
- intentkit/skills/twitter/twitter.png +0 -0
- intentkit/skills/unrealspeech/__init__.py +55 -0
- intentkit/skills/unrealspeech/base.py +21 -0
- intentkit/skills/unrealspeech/schema.json +100 -0
- intentkit/skills/unrealspeech/text_to_speech.py +177 -0
- intentkit/skills/unrealspeech/unrealspeech.jpg +0 -0
- intentkit/skills/venice_audio/__init__.py +106 -0
- intentkit/skills/venice_audio/base.py +119 -0
- intentkit/skills/venice_audio/input.py +41 -0
- intentkit/skills/venice_audio/schema.json +152 -0
- intentkit/skills/venice_audio/venice_audio.py +240 -0
- intentkit/skills/venice_audio/venice_logo.jpg +0 -0
- intentkit/skills/venice_image/README.md +119 -0
- intentkit/skills/venice_image/__init__.py +154 -0
- intentkit/skills/venice_image/api.py +138 -0
- intentkit/skills/venice_image/base.py +188 -0
- intentkit/skills/venice_image/config.py +35 -0
- intentkit/skills/venice_image/image_enhance/README.md +119 -0
- intentkit/skills/venice_image/image_enhance/__init__.py +0 -0
- intentkit/skills/venice_image/image_enhance/image_enhance.py +80 -0
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +23 -0
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +40 -0
- intentkit/skills/venice_image/image_generation/README.md +144 -0
- intentkit/skills/venice_image/image_generation/__init__.py +0 -0
- intentkit/skills/venice_image/image_generation/image_generation_base.py +117 -0
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -0
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -0
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -0
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -0
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -0
- intentkit/skills/venice_image/image_upscale/README.md +111 -0
- intentkit/skills/venice_image/image_upscale/__init__.py +0 -0
- intentkit/skills/venice_image/image_upscale/image_upscale.py +90 -0
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +23 -0
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -0
- intentkit/skills/venice_image/image_vision/README.md +112 -0
- intentkit/skills/venice_image/image_vision/__init__.py +0 -0
- intentkit/skills/venice_image/image_vision/image_vision.py +100 -0
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -0
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -0
- intentkit/skills/venice_image/schema.json +267 -0
- intentkit/skills/venice_image/utils.py +78 -0
- intentkit/skills/venice_image/venice_image.jpg +0 -0
- intentkit/skills/web_scraper/README.md +82 -0
- intentkit/skills/web_scraper/__init__.py +92 -0
- intentkit/skills/web_scraper/base.py +21 -0
- intentkit/skills/web_scraper/langchain.png +0 -0
- intentkit/skills/web_scraper/schema.json +115 -0
- intentkit/skills/web_scraper/scrape_and_index.py +327 -0
- intentkit/utils/__init__.py +1 -0
- intentkit/utils/chain.py +436 -0
- intentkit/utils/error.py +134 -0
- intentkit/utils/logging.py +70 -0
- intentkit/utils/middleware.py +61 -0
- intentkit/utils/random.py +16 -0
- intentkit/utils/s3.py +267 -0
- intentkit/utils/slack_alert.py +79 -0
- intentkit/utils/tx.py +37 -0
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/METADATA +1 -1
- intentkit-0.5.2.dist-info/RECORD +365 -0
- intentkit-0.5.0.dist-info/RECORD +0 -4
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/WHEEL +0 -0
- {intentkit-0.5.0.dist-info → intentkit-0.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""Tool for fetching chain TVL data via DeFi Llama API."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional, Type
|
|
4
|
+
|
|
5
|
+
from langchain.schema.runnable import RunnableConfig
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from intentkit.skills.defillama.api import fetch_chains
|
|
9
|
+
from intentkit.skills.defillama.base import DefiLlamaBaseTool
|
|
10
|
+
|
|
11
|
+
FETCH_CHAINS_PROMPT = """
|
|
12
|
+
This tool fetches current Total Value Locked (TVL) data for all blockchains tracked by DeFi Llama.
|
|
13
|
+
No input parameters are required. Returns a comprehensive list including:
|
|
14
|
+
- Chain name and identifiers
|
|
15
|
+
- Current TVL in USD
|
|
16
|
+
- Chain metadata (token symbol, IDs)
|
|
17
|
+
- Aggregated total TVL across all chains
|
|
18
|
+
Returns the complete list of chains and total TVL or an error if the request fails.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ChainTVLData(BaseModel):
|
|
23
|
+
"""Model representing TVL data for a single chain."""
|
|
24
|
+
|
|
25
|
+
name: str = Field(..., description="Chain name")
|
|
26
|
+
tvl: float = Field(..., description="Total Value Locked in USD")
|
|
27
|
+
gecko_id: Optional[str] = Field(None, description="CoinGecko identifier")
|
|
28
|
+
token_symbol: Optional[str] = Field(
|
|
29
|
+
None, alias="tokenSymbol", description="Native token symbol"
|
|
30
|
+
)
|
|
31
|
+
cmc_id: Optional[str] = Field(
|
|
32
|
+
None, alias="cmcId", description="CoinMarketCap identifier"
|
|
33
|
+
)
|
|
34
|
+
chain_id: Optional[int | str] = Field(
|
|
35
|
+
None, alias="chainId", description="Chain identifier"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class FetchChainsInput(BaseModel):
|
|
40
|
+
"""Input schema for fetching all chains' TVL data.
|
|
41
|
+
|
|
42
|
+
This endpoint doesn't require any parameters as it returns
|
|
43
|
+
TVL data for all chains.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class FetchChainsResponse(BaseModel):
|
|
50
|
+
"""Response schema for all chains' TVL data."""
|
|
51
|
+
|
|
52
|
+
chains: List[ChainTVLData] = Field(
|
|
53
|
+
default_factory=list, description="List of chains with their TVL data"
|
|
54
|
+
)
|
|
55
|
+
total_tvl: float = Field(..., description="Total TVL across all chains in USD")
|
|
56
|
+
error: Optional[str] = Field(None, description="Error message if any")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class DefiLlamaFetchChains(DefiLlamaBaseTool):
|
|
60
|
+
"""Tool for fetching current TVL data for all blockchains.
|
|
61
|
+
|
|
62
|
+
This tool retrieves the current Total Value Locked (TVL) for all chains
|
|
63
|
+
tracked by DeFi Llama, including chain identifiers and metadata.
|
|
64
|
+
|
|
65
|
+
Example:
|
|
66
|
+
chains_tool = DefiLlamaFetchChains(
|
|
67
|
+
skill_store=store,
|
|
68
|
+
agent_id="agent_123",
|
|
69
|
+
agent_store=agent_store
|
|
70
|
+
)
|
|
71
|
+
result = await chains_tool._arun()
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
name: str = "defillama_fetch_chains"
|
|
75
|
+
description: str = FETCH_CHAINS_PROMPT
|
|
76
|
+
args_schema: Type[BaseModel] = FetchChainsInput
|
|
77
|
+
|
|
78
|
+
async def _arun(self, config: RunnableConfig) -> FetchChainsResponse:
|
|
79
|
+
"""Fetch TVL data for all chains.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
FetchChainsResponse containing chain TVL data and total TVL or error
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
# Check rate limiting
|
|
86
|
+
context = self.context_from_config(config)
|
|
87
|
+
is_rate_limited, error_msg = await self.check_rate_limit(context)
|
|
88
|
+
if is_rate_limited:
|
|
89
|
+
return FetchChainsResponse(chains=[], total_tvl=0, error=error_msg)
|
|
90
|
+
|
|
91
|
+
# Fetch chains data from API
|
|
92
|
+
result = await fetch_chains()
|
|
93
|
+
|
|
94
|
+
# Check for API errors
|
|
95
|
+
if isinstance(result, dict) and "error" in result:
|
|
96
|
+
return FetchChainsResponse(
|
|
97
|
+
chains=[], total_tvl=0, error=result["error"]
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Parse chains data and calculate total TVL
|
|
101
|
+
chains = [ChainTVLData(**chain_data) for chain_data in result]
|
|
102
|
+
total_tvl = sum(chain.tvl for chain in chains)
|
|
103
|
+
|
|
104
|
+
return FetchChainsResponse(chains=chains, total_tvl=total_tvl)
|
|
105
|
+
|
|
106
|
+
except Exception as e:
|
|
107
|
+
return FetchChainsResponse(chains=[], total_tvl=0, error=str(e))
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Tool for fetching total historical TVL via DeFiLlama API."""
|
|
2
|
+
|
|
3
|
+
from typing import List, Type
|
|
4
|
+
|
|
5
|
+
from langchain.schema.runnable import RunnableConfig
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from intentkit.skills.defillama.api import fetch_historical_tvl
|
|
9
|
+
from intentkit.skills.defillama.base import DefiLlamaBaseTool
|
|
10
|
+
|
|
11
|
+
FETCH_TOTAL_HISTORICAL_TVL_PROMPT = """
|
|
12
|
+
This tool fetches historical Total Value Locked (TVL) data across all blockchains.
|
|
13
|
+
Returns a time series of aggregate TVL values with their corresponding dates.
|
|
14
|
+
No input parameters are required as this endpoint returns global DeFi TVL data.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class HistoricalTVLDataPoint(BaseModel):
|
|
19
|
+
"""Model representing a single TVL data point."""
|
|
20
|
+
|
|
21
|
+
date: int = Field(..., description="Unix timestamp of the TVL measurement")
|
|
22
|
+
tvl: float = Field(..., description="Total Value Locked in USD at this timestamp")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FetchHistoricalTVLInput(BaseModel):
|
|
26
|
+
"""Input schema for fetching historical TVL data.
|
|
27
|
+
|
|
28
|
+
This endpoint doesn't require any parameters as it returns
|
|
29
|
+
global TVL data across all chains.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class FetchHistoricalTVLResponse(BaseModel):
|
|
36
|
+
"""Response schema for historical TVL data."""
|
|
37
|
+
|
|
38
|
+
data: List[HistoricalTVLDataPoint] = Field(
|
|
39
|
+
default_factory=list,
|
|
40
|
+
description="List of historical TVL data points across all chains",
|
|
41
|
+
)
|
|
42
|
+
error: str | None = Field(default=None, description="Error message if any")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class DefiLlamaFetchHistoricalTvl(DefiLlamaBaseTool):
|
|
46
|
+
"""Tool for fetching historical TVL data across all blockchains.
|
|
47
|
+
|
|
48
|
+
This tool fetches the complete Total Value Locked (TVL) history aggregated
|
|
49
|
+
across all chains using the DeFiLlama API. It includes rate limiting to
|
|
50
|
+
ensure reliable data retrieval.
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
tvl_tool = DefiLlamaFetchHistoricalTvl(
|
|
54
|
+
skill_store=store,
|
|
55
|
+
agent_id="agent_123",
|
|
56
|
+
agent_store=agent_store
|
|
57
|
+
)
|
|
58
|
+
result = await tvl_tool._arun()
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
name: str = "defillama_fetch_total_historical_tvl"
|
|
62
|
+
description: str = FETCH_TOTAL_HISTORICAL_TVL_PROMPT
|
|
63
|
+
args_schema: Type[BaseModel] = FetchHistoricalTVLInput
|
|
64
|
+
|
|
65
|
+
async def _arun(self, config: RunnableConfig) -> FetchHistoricalTVLResponse:
|
|
66
|
+
"""Fetch historical TVL data across all chains.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
FetchHistoricalTVLResponse containing TVL history or error
|
|
70
|
+
"""
|
|
71
|
+
try:
|
|
72
|
+
# Check rate limiting
|
|
73
|
+
context = self.context_from_config(config)
|
|
74
|
+
is_rate_limited, error_msg = await self.check_rate_limit(context)
|
|
75
|
+
if is_rate_limited:
|
|
76
|
+
return FetchHistoricalTVLResponse(error=error_msg)
|
|
77
|
+
|
|
78
|
+
# Fetch TVL history from API
|
|
79
|
+
result = await fetch_historical_tvl()
|
|
80
|
+
|
|
81
|
+
# Check for API errors
|
|
82
|
+
if isinstance(result, dict) and "error" in result:
|
|
83
|
+
return FetchHistoricalTVLResponse(error=result["error"])
|
|
84
|
+
|
|
85
|
+
# Parse response into our schema
|
|
86
|
+
data_points = [HistoricalTVLDataPoint(**point) for point in result]
|
|
87
|
+
|
|
88
|
+
return FetchHistoricalTVLResponse(data=data_points)
|
|
89
|
+
|
|
90
|
+
except Exception as e:
|
|
91
|
+
return FetchHistoricalTVLResponse(error=str(e))
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"""Tool for fetching specific protocol details via DeFi Llama API."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, List, Optional, Type
|
|
4
|
+
|
|
5
|
+
from langchain.schema.runnable import RunnableConfig
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from intentkit.skills.defillama.api import fetch_protocol
|
|
9
|
+
from intentkit.skills.defillama.base import DefiLlamaBaseTool
|
|
10
|
+
|
|
11
|
+
FETCH_PROTOCOL_PROMPT = """
|
|
12
|
+
This tool fetches comprehensive details about a specific DeFi protocol.
|
|
13
|
+
Provide the protocol identifier (e.g., "aave", "curve") to get detailed information including:
|
|
14
|
+
- Basic protocol information (name, description, website)
|
|
15
|
+
- TVL data across different chains
|
|
16
|
+
- Token information and historical amounts
|
|
17
|
+
- Social media and development links
|
|
18
|
+
- Funding history and significant events
|
|
19
|
+
- Market metrics and related protocols
|
|
20
|
+
Returns complete protocol details or an error if the protocol is not found.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TokenAmount(BaseModel):
|
|
25
|
+
"""Model representing token amounts at a specific date."""
|
|
26
|
+
|
|
27
|
+
date: int = Field(..., description="Unix timestamp")
|
|
28
|
+
tokens: Dict[str, float] = Field(..., description="Token amounts keyed by symbol")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ChainTVLData(BaseModel):
|
|
32
|
+
"""Model representing TVL data for a specific chain."""
|
|
33
|
+
|
|
34
|
+
tvl: List[Dict[str, float]] = Field(..., description="Historical TVL data points")
|
|
35
|
+
tokens: Optional[Dict[str, float]] = Field(
|
|
36
|
+
None, description="Current token amounts"
|
|
37
|
+
)
|
|
38
|
+
tokensInUsd: Optional[Dict[str, float]] = Field(
|
|
39
|
+
None, description="Current token amounts in USD"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class HistoricalTVL(BaseModel):
|
|
44
|
+
"""Model representing a historical TVL data point."""
|
|
45
|
+
|
|
46
|
+
date: int = Field(..., description="Unix timestamp")
|
|
47
|
+
totalLiquidityUSD: float = Field(..., description="Total TVL in USD")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Raise(BaseModel):
|
|
51
|
+
"""Model representing a funding round."""
|
|
52
|
+
|
|
53
|
+
date: int = Field(..., description="Funding date")
|
|
54
|
+
name: str = Field(..., description="Protocol name")
|
|
55
|
+
round: str = Field(..., description="Funding round type")
|
|
56
|
+
amount: float = Field(..., description="Amount raised in millions")
|
|
57
|
+
chains: List[str] = Field(..., description="Chains involved")
|
|
58
|
+
sector: str = Field(..., description="Business sector")
|
|
59
|
+
category: str = Field(..., description="Protocol category")
|
|
60
|
+
categoryGroup: str = Field(..., description="Category group")
|
|
61
|
+
source: str = Field(..., description="Information source")
|
|
62
|
+
leadInvestors: List[str] = Field(default_factory=list, description="Lead investors")
|
|
63
|
+
otherInvestors: List[str] = Field(
|
|
64
|
+
default_factory=list, description="Other investors"
|
|
65
|
+
)
|
|
66
|
+
valuation: Optional[float] = Field(None, description="Valuation at time of raise")
|
|
67
|
+
defillamaId: Optional[str] = Field(None, description="DefiLlama ID")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Hallmark(BaseModel):
|
|
71
|
+
"""Model representing a significant protocol event."""
|
|
72
|
+
|
|
73
|
+
timestamp: int
|
|
74
|
+
description: str
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ProtocolDetail(BaseModel):
|
|
78
|
+
"""Model representing detailed protocol information."""
|
|
79
|
+
|
|
80
|
+
# Basic Info
|
|
81
|
+
id: str = Field(..., description="Protocol unique identifier")
|
|
82
|
+
name: str = Field(..., description="Protocol name")
|
|
83
|
+
address: Optional[str] = Field(None, description="Protocol address")
|
|
84
|
+
symbol: str = Field(..., description="Protocol token symbol")
|
|
85
|
+
url: str = Field(..., description="Protocol website")
|
|
86
|
+
description: str = Field(..., description="Protocol description")
|
|
87
|
+
logo: str = Field(..., description="Logo URL")
|
|
88
|
+
|
|
89
|
+
# Chain Info
|
|
90
|
+
chains: List[str] = Field(default_factory=list, description="Supported chains")
|
|
91
|
+
currentChainTvls: Dict[str, float] = Field(..., description="Current TVL by chain")
|
|
92
|
+
chainTvls: Dict[str, ChainTVLData] = Field(
|
|
93
|
+
..., description="Historical TVL data by chain"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Identifiers
|
|
97
|
+
gecko_id: Optional[str] = Field(None, description="CoinGecko ID")
|
|
98
|
+
cmcId: Optional[str] = Field(None, description="CoinMarketCap ID")
|
|
99
|
+
|
|
100
|
+
# Social & Development
|
|
101
|
+
twitter: Optional[str] = Field(None, description="Twitter handle")
|
|
102
|
+
treasury: Optional[str] = Field(None, description="Treasury information")
|
|
103
|
+
governanceID: Optional[List[str]] = Field(
|
|
104
|
+
None, description="Governance identifiers"
|
|
105
|
+
)
|
|
106
|
+
github: Optional[List[str]] = Field(None, description="GitHub repositories")
|
|
107
|
+
|
|
108
|
+
# Protocol Relationships
|
|
109
|
+
isParentProtocol: Optional[bool] = Field(
|
|
110
|
+
None, description="Whether this is a parent protocol"
|
|
111
|
+
)
|
|
112
|
+
otherProtocols: Optional[List[str]] = Field(None, description="Related protocols")
|
|
113
|
+
|
|
114
|
+
# Historical Data
|
|
115
|
+
tokens: List[TokenAmount] = Field(
|
|
116
|
+
default_factory=list, description="Historical token amounts"
|
|
117
|
+
)
|
|
118
|
+
tvl: List[HistoricalTVL] = Field(..., description="Historical TVL data points")
|
|
119
|
+
raises: Optional[List[Raise]] = Field(None, description="Funding rounds")
|
|
120
|
+
hallmarks: Optional[List[Hallmark]] = Field(None, description="Significant events")
|
|
121
|
+
|
|
122
|
+
# Market Data
|
|
123
|
+
mcap: Optional[float] = Field(None, description="Market capitalization")
|
|
124
|
+
metrics: Dict = Field(default_factory=dict, description="Additional metrics")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class DefiLlamaProtocolInput(BaseModel):
|
|
128
|
+
"""Input model for fetching protocol details."""
|
|
129
|
+
|
|
130
|
+
protocol: str = Field(..., description="Protocol identifier to fetch")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class DefiLlamaProtocolOutput(BaseModel):
|
|
134
|
+
"""Output model for the protocol fetching tool."""
|
|
135
|
+
|
|
136
|
+
protocol: Optional[ProtocolDetail] = Field(None, description="Protocol details")
|
|
137
|
+
error: Optional[str] = Field(None, description="Error message if any")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class DefiLlamaFetchProtocol(DefiLlamaBaseTool):
|
|
141
|
+
"""Tool for fetching detailed protocol information from DeFi Llama.
|
|
142
|
+
|
|
143
|
+
This tool retrieves comprehensive information about a specific protocol,
|
|
144
|
+
including TVL history, token breakdowns, and metadata.
|
|
145
|
+
|
|
146
|
+
Example:
|
|
147
|
+
protocol_tool = DefiLlamaFetchProtocol(
|
|
148
|
+
skill_store=store,
|
|
149
|
+
agent_id="agent_123",
|
|
150
|
+
agent_store=agent_store
|
|
151
|
+
)
|
|
152
|
+
result = await protocol_tool._arun(protocol="aave")
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
name: str = "defillama_fetch_protocol"
|
|
156
|
+
description: str = FETCH_PROTOCOL_PROMPT
|
|
157
|
+
args_schema: Type[BaseModel] = DefiLlamaProtocolInput
|
|
158
|
+
|
|
159
|
+
async def _arun(
|
|
160
|
+
self, config: RunnableConfig, protocol: str
|
|
161
|
+
) -> DefiLlamaProtocolOutput:
|
|
162
|
+
"""Fetch detailed information about a specific protocol.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
config: Runnable configuration
|
|
166
|
+
protocol: Protocol identifier to fetch
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
DefiLlamaProtocolOutput containing protocol details or error
|
|
170
|
+
"""
|
|
171
|
+
try:
|
|
172
|
+
# Check rate limiting
|
|
173
|
+
context = self.context_from_config(config)
|
|
174
|
+
is_rate_limited, error_msg = await self.check_rate_limit(context)
|
|
175
|
+
if is_rate_limited:
|
|
176
|
+
return DefiLlamaProtocolOutput(error=error_msg)
|
|
177
|
+
|
|
178
|
+
# Fetch protocol data from API
|
|
179
|
+
result = await fetch_protocol(protocol)
|
|
180
|
+
|
|
181
|
+
if isinstance(result, dict) and "error" in result:
|
|
182
|
+
return DefiLlamaProtocolOutput(error=result["error"])
|
|
183
|
+
|
|
184
|
+
# Process hallmarks if present
|
|
185
|
+
hallmarks = None
|
|
186
|
+
if "hallmarks" in result:
|
|
187
|
+
hallmarks = [
|
|
188
|
+
Hallmark(timestamp=h[0], description=h[1])
|
|
189
|
+
for h in result.get("hallmarks", [])
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
# Create raises objects if present
|
|
193
|
+
raises = None
|
|
194
|
+
if "raises" in result:
|
|
195
|
+
raises = [Raise(**r) for r in result.get("raises", [])]
|
|
196
|
+
|
|
197
|
+
# Create protocol detail object
|
|
198
|
+
protocol_detail = ProtocolDetail(
|
|
199
|
+
**{k: v for k, v in result.items() if k not in ["hallmarks", "raises"]},
|
|
200
|
+
hallmarks=hallmarks,
|
|
201
|
+
raises=raises,
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
return DefiLlamaProtocolOutput(protocol=protocol_detail)
|
|
205
|
+
|
|
206
|
+
except Exception as e:
|
|
207
|
+
return DefiLlamaProtocolOutput(error=str(e))
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Tool for fetching protocol TVL via DeFiLlama API."""
|
|
2
|
+
|
|
3
|
+
from typing import Type
|
|
4
|
+
|
|
5
|
+
from langchain.schema.runnable import RunnableConfig
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from intentkit.skills.defillama.api import fetch_protocol_current_tvl
|
|
9
|
+
from intentkit.skills.defillama.base import DefiLlamaBaseTool
|
|
10
|
+
|
|
11
|
+
FETCH_TVL_PROMPT = """
|
|
12
|
+
This tool fetches the current Total Value Locked (TVL) for a specific DeFi protocol.
|
|
13
|
+
Provide the protocol slug (e.g., "aave", "curve") to get its current TVL in USD.
|
|
14
|
+
Returns the normalized protocol name and its TVL value.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FetchProtocolCurrentTVLInput(BaseModel):
|
|
19
|
+
"""Input schema for fetching current protocol TVL."""
|
|
20
|
+
|
|
21
|
+
protocol: str = Field(
|
|
22
|
+
..., description="Protocol slug to fetch TVL for (e.g., 'aave', 'curve')"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class FetchProtocolCurrentTVLResponse(BaseModel):
|
|
27
|
+
"""Response schema for current protocol TVL."""
|
|
28
|
+
|
|
29
|
+
protocol: str = Field(..., description="Normalized protocol slug")
|
|
30
|
+
tvl: float = Field(..., description="Current Total Value Locked in USD")
|
|
31
|
+
error: str | None = Field(default=None, description="Error message if any")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DefiLlamaFetchProtocolCurrentTvl(DefiLlamaBaseTool):
|
|
35
|
+
"""Tool for fetching current TVL of a specific DeFi protocol.
|
|
36
|
+
|
|
37
|
+
This tool fetches the current Total Value Locked (TVL) for a given protocol
|
|
38
|
+
using the DeFiLlama API. It includes rate limiting to avoid API abuse.
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
tvl_tool = DefiLlamaFetchProtocolCurrentTvl(
|
|
42
|
+
skill_store=store,
|
|
43
|
+
agent_id="agent_123",
|
|
44
|
+
agent_store=agent_store
|
|
45
|
+
)
|
|
46
|
+
result = await tvl_tool._arun(protocol="aave")
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
name: str = "defillama_fetch_protocol_tvl"
|
|
50
|
+
description: str = FETCH_TVL_PROMPT
|
|
51
|
+
args_schema: Type[BaseModel] = FetchProtocolCurrentTVLInput
|
|
52
|
+
|
|
53
|
+
async def _arun(
|
|
54
|
+
self, config: RunnableConfig, protocol: str
|
|
55
|
+
) -> FetchProtocolCurrentTVLResponse:
|
|
56
|
+
"""Fetch current TVL for the given protocol.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
config: Runnable configuration
|
|
60
|
+
protocol: DeFi protocol slug (e.g., "aave", "curve")
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
FetchProtocolCurrentTVLResponse containing protocol name, TVL value or error
|
|
64
|
+
"""
|
|
65
|
+
try:
|
|
66
|
+
# Check rate limiting
|
|
67
|
+
context = self.context_from_config(config)
|
|
68
|
+
is_rate_limited, error_msg = await self.check_rate_limit(context)
|
|
69
|
+
if is_rate_limited:
|
|
70
|
+
return FetchProtocolCurrentTVLResponse(
|
|
71
|
+
protocol=protocol, tvl=0, error=error_msg
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Normalize protocol slug
|
|
75
|
+
normalized_protocol = protocol.lower().replace(" ", "-")
|
|
76
|
+
|
|
77
|
+
# Fetch TVL from API
|
|
78
|
+
result = await fetch_protocol_current_tvl(normalized_protocol)
|
|
79
|
+
|
|
80
|
+
# Check for API errors
|
|
81
|
+
if isinstance(result, dict) and "error" in result:
|
|
82
|
+
return FetchProtocolCurrentTVLResponse(
|
|
83
|
+
protocol=normalized_protocol, tvl=0, error=result["error"]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return FetchProtocolCurrentTVLResponse(
|
|
87
|
+
protocol=normalized_protocol, tvl=float(result)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
except Exception as e:
|
|
91
|
+
return FetchProtocolCurrentTVLResponse(
|
|
92
|
+
protocol=protocol, tvl=0, error=str(e)
|
|
93
|
+
)
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""Tool for fetching all protocols via DeFi Llama API."""
|
|
2
|
+
|
|
3
|
+
from typing import Dict, List, Optional, Type, Union
|
|
4
|
+
|
|
5
|
+
from langchain.schema.runnable import RunnableConfig
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from intentkit.skills.defillama.api import fetch_protocols
|
|
9
|
+
from intentkit.skills.defillama.base import DefiLlamaBaseTool
|
|
10
|
+
|
|
11
|
+
FETCH_PROTOCOLS_PROMPT = """
|
|
12
|
+
This tool fetches information about all protocols tracked by DeFi Llama.
|
|
13
|
+
No input parameters are required. Returns comprehensive data for each protocol including:
|
|
14
|
+
- Basic information (name, description, website, logo)
|
|
15
|
+
- TVL metrics (total and per-chain breakdowns)
|
|
16
|
+
- Audit status and security information
|
|
17
|
+
- Token details and market metrics
|
|
18
|
+
- Chain support and deployment information
|
|
19
|
+
- Social media and development links
|
|
20
|
+
- Protocol relationships (forks, oracles)
|
|
21
|
+
- Historical events and significant updates
|
|
22
|
+
Returns the complete list of protocols or an error if the request fails.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Hallmark(BaseModel):
|
|
27
|
+
"""Model representing a protocol hallmark (significant event)."""
|
|
28
|
+
|
|
29
|
+
timestamp: int
|
|
30
|
+
description: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class Protocol(BaseModel):
|
|
34
|
+
"""Model representing a DeFi protocol."""
|
|
35
|
+
|
|
36
|
+
# Basic Info
|
|
37
|
+
id: str = Field(..., description="Protocol unique identifier")
|
|
38
|
+
name: str = Field(..., description="Protocol name")
|
|
39
|
+
address: Optional[str] = Field(None, description="Protocol's main contract address")
|
|
40
|
+
symbol: str = Field(..., description="Protocol token symbol")
|
|
41
|
+
url: Optional[str] = Field(None, description="Protocol website")
|
|
42
|
+
description: Optional[str] = Field(None, description="Protocol description")
|
|
43
|
+
chain: Optional[str] = Field(None, description="Main chain of the protocol")
|
|
44
|
+
logo: Optional[str] = Field(None, description="URL to protocol logo")
|
|
45
|
+
|
|
46
|
+
# Audit Information
|
|
47
|
+
audits: Union[str, int] = Field("0", description="Number of audits")
|
|
48
|
+
audit_note: Optional[str] = Field(None, description="Additional audit information")
|
|
49
|
+
audit_links: Optional[List[str]] = Field(None, description="Links to audit reports")
|
|
50
|
+
|
|
51
|
+
# External IDs
|
|
52
|
+
gecko_id: Optional[str] = Field(None, description="CoinGecko ID")
|
|
53
|
+
cmcId: Optional[Union[str, int]] = Field(None, description="CoinMarketCap ID")
|
|
54
|
+
|
|
55
|
+
# Classification
|
|
56
|
+
category: str = Field(..., description="Protocol category")
|
|
57
|
+
chains: List[str] = Field(
|
|
58
|
+
default_factory=list, description="Chains the protocol operates on"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Module and Related Info
|
|
62
|
+
module: str = Field(..., description="Module name in DefiLlama")
|
|
63
|
+
parentProtocol: Optional[str] = Field(
|
|
64
|
+
None, description="Parent protocol identifier"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Social and Development
|
|
68
|
+
twitter: Optional[str] = Field(None, description="Twitter handle")
|
|
69
|
+
github: Optional[List[str]] = Field(None, description="GitHub organization names")
|
|
70
|
+
|
|
71
|
+
# Protocol Relationships
|
|
72
|
+
oracles: List[str] = Field(default_factory=list, description="Oracle services used")
|
|
73
|
+
forkedFrom: List[str] = Field(
|
|
74
|
+
default_factory=list, description="Protocols this one was forked from"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Additional Metadata
|
|
78
|
+
methodology: Optional[str] = Field(None, description="TVL calculation methodology")
|
|
79
|
+
listedAt: Optional[int] = Field(
|
|
80
|
+
None, description="Timestamp when protocol was listed"
|
|
81
|
+
)
|
|
82
|
+
openSource: Optional[bool] = Field(
|
|
83
|
+
None, description="Whether protocol is open source"
|
|
84
|
+
)
|
|
85
|
+
treasury: Optional[str] = Field(None, description="Treasury information")
|
|
86
|
+
misrepresentedTokens: Optional[bool] = Field(
|
|
87
|
+
None, description="Whether tokens are misrepresented"
|
|
88
|
+
)
|
|
89
|
+
hallmarks: Optional[List[Hallmark]] = Field(
|
|
90
|
+
None, description="Significant protocol events"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# TVL Related Data
|
|
94
|
+
tvl: Optional[float] = Field(None, description="Total Value Locked in USD")
|
|
95
|
+
chainTvls: Dict[str, float] = Field(
|
|
96
|
+
default_factory=dict,
|
|
97
|
+
description="TVL breakdown by chain including special types (staking, borrowed, etc.)",
|
|
98
|
+
)
|
|
99
|
+
change_1h: Optional[float] = Field(None, description="1 hour TVL change percentage")
|
|
100
|
+
change_1d: Optional[float] = Field(None, description="1 day TVL change percentage")
|
|
101
|
+
change_7d: Optional[float] = Field(None, description="7 day TVL change percentage")
|
|
102
|
+
|
|
103
|
+
# Additional TVL Components
|
|
104
|
+
staking: Optional[float] = Field(None, description="Value in staking")
|
|
105
|
+
pool2: Optional[float] = Field(None, description="Value in pool2")
|
|
106
|
+
borrowed: Optional[float] = Field(None, description="Value borrowed")
|
|
107
|
+
|
|
108
|
+
# Token Information
|
|
109
|
+
tokenBreakdowns: Dict[str, float] = Field(
|
|
110
|
+
default_factory=dict, description="TVL breakdown by token"
|
|
111
|
+
)
|
|
112
|
+
mcap: Optional[float] = Field(None, description="Market capitalization")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class DefiLlamaProtocolsOutput(BaseModel):
|
|
116
|
+
"""Output model for the protocols fetching tool."""
|
|
117
|
+
|
|
118
|
+
protocols: List[Protocol] = Field(
|
|
119
|
+
default_factory=list, description="List of fetched protocols"
|
|
120
|
+
)
|
|
121
|
+
error: Optional[str] = Field(None, description="Error message if any")
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class DefiLlamaFetchProtocols(DefiLlamaBaseTool):
|
|
125
|
+
"""Tool for fetching all protocols from DeFi Llama.
|
|
126
|
+
|
|
127
|
+
This tool retrieves information about all protocols tracked by DeFi Llama,
|
|
128
|
+
including their TVL, supported chains, and related metrics.
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
protocols_tool = DefiLlamaFetchProtocols(
|
|
132
|
+
skill_store=store,
|
|
133
|
+
agent_id="agent_123",
|
|
134
|
+
agent_store=agent_store
|
|
135
|
+
)
|
|
136
|
+
result = await protocols_tool._arun()
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
name: str = "defillama_fetch_protocols"
|
|
140
|
+
description: str = FETCH_PROTOCOLS_PROMPT
|
|
141
|
+
|
|
142
|
+
class EmptyArgsSchema(BaseModel):
|
|
143
|
+
"""Empty schema for no input parameters."""
|
|
144
|
+
|
|
145
|
+
pass
|
|
146
|
+
|
|
147
|
+
args_schema: Type[BaseModel] = EmptyArgsSchema
|
|
148
|
+
|
|
149
|
+
async def _arun(self, config: RunnableConfig) -> DefiLlamaProtocolsOutput:
|
|
150
|
+
"""Fetch information about all protocols.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
DefiLlamaProtocolsOutput containing list of protocols or error
|
|
154
|
+
"""
|
|
155
|
+
try:
|
|
156
|
+
# Check rate limiting
|
|
157
|
+
context = self.context_from_config(config)
|
|
158
|
+
is_rate_limited, error_msg = await self.check_rate_limit(context)
|
|
159
|
+
if is_rate_limited:
|
|
160
|
+
return DefiLlamaProtocolsOutput(error=error_msg)
|
|
161
|
+
|
|
162
|
+
# Fetch protocols from API
|
|
163
|
+
result = await fetch_protocols()
|
|
164
|
+
|
|
165
|
+
if isinstance(result, dict) and "error" in result:
|
|
166
|
+
return DefiLlamaProtocolsOutput(error=result["error"])
|
|
167
|
+
|
|
168
|
+
# Convert raw data to Protocol models
|
|
169
|
+
protocols = []
|
|
170
|
+
for protocol_data in result:
|
|
171
|
+
try:
|
|
172
|
+
# Process hallmarks if present
|
|
173
|
+
hallmarks = None
|
|
174
|
+
if "hallmarks" in protocol_data and protocol_data["hallmarks"]:
|
|
175
|
+
hallmarks = [
|
|
176
|
+
Hallmark(timestamp=h[0], description=h[1])
|
|
177
|
+
for h in protocol_data["hallmarks"]
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
# Create protocol model
|
|
181
|
+
protocol = Protocol(
|
|
182
|
+
**{k: v for k, v in protocol_data.items() if k != "hallmarks"},
|
|
183
|
+
hallmarks=hallmarks,
|
|
184
|
+
)
|
|
185
|
+
protocols.append(protocol)
|
|
186
|
+
except Exception as e:
|
|
187
|
+
# Log error for individual protocol processing but continue with others
|
|
188
|
+
print(
|
|
189
|
+
f"Error processing protocol {protocol_data.get('name', 'unknown')}: {str(e)}"
|
|
190
|
+
)
|
|
191
|
+
continue
|
|
192
|
+
|
|
193
|
+
return DefiLlamaProtocolsOutput(protocols=protocols)
|
|
194
|
+
|
|
195
|
+
except Exception as e:
|
|
196
|
+
return DefiLlamaProtocolsOutput(error=str(e))
|