intentkit 0.7.5.dev3__py3-none-any.whl → 0.8.34.dev7__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.
- intentkit/MANIFEST.in +14 -0
- intentkit/README.md +88 -0
- intentkit/__init__.py +6 -4
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +15 -8
- intentkit/abstracts/skill.py +6 -144
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/__init__.py +9 -2
- intentkit/clients/cdp.py +129 -153
- intentkit/{utils → clients}/s3.py +109 -34
- intentkit/clients/twitter.py +83 -62
- intentkit/clients/web3.py +4 -7
- intentkit/config/config.py +123 -90
- intentkit/core/account_checking.py +802 -0
- intentkit/core/agent.py +313 -498
- intentkit/core/asset.py +267 -0
- intentkit/core/chat.py +5 -3
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +49 -41
- intentkit/core/draft.py +201 -0
- intentkit/core/draft_chat.py +118 -0
- intentkit/core/engine.py +378 -287
- intentkit/core/manager/__init__.py +25 -0
- intentkit/core/manager/engine.py +220 -0
- intentkit/core/manager/service.py +172 -0
- intentkit/core/manager/skills.py +178 -0
- intentkit/core/middleware.py +231 -0
- intentkit/core/prompt.py +74 -114
- intentkit/core/scheduler.py +143 -0
- intentkit/core/statistics.py +168 -0
- intentkit/models/agent.py +931 -518
- intentkit/models/agent_data.py +165 -106
- intentkit/models/agent_schema.json +38 -251
- intentkit/models/app_setting.py +15 -13
- intentkit/models/chat.py +86 -140
- intentkit/models/credit.py +182 -162
- intentkit/models/db.py +42 -23
- intentkit/models/db_mig.py +120 -3
- intentkit/models/draft.py +222 -0
- intentkit/models/llm.csv +31 -0
- intentkit/models/llm.py +262 -370
- intentkit/models/redis.py +6 -4
- intentkit/models/skill.py +222 -101
- intentkit/models/skills.csv +173 -0
- intentkit/models/team.py +189 -0
- intentkit/models/user.py +103 -31
- intentkit/skills/acolyt/__init__.py +2 -9
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +4 -9
- intentkit/skills/acolyt/schema.json +4 -3
- intentkit/skills/aixbt/__init__.py +2 -13
- intentkit/skills/aixbt/base.py +1 -7
- intentkit/skills/aixbt/projects.py +14 -15
- intentkit/skills/aixbt/schema.json +4 -4
- intentkit/skills/allora/__init__.py +2 -9
- intentkit/skills/allora/base.py +4 -9
- intentkit/skills/allora/price.py +3 -4
- intentkit/skills/allora/schema.json +3 -2
- intentkit/skills/base.py +241 -41
- intentkit/skills/basename/__init__.py +51 -0
- intentkit/skills/basename/base.py +11 -0
- intentkit/skills/basename/basename.svg +11 -0
- intentkit/skills/basename/schema.json +58 -0
- intentkit/skills/carv/__init__.py +115 -121
- intentkit/skills/carv/base.py +184 -185
- intentkit/skills/carv/fetch_news.py +3 -3
- intentkit/skills/carv/onchain_query.py +4 -4
- intentkit/skills/carv/schema.json +134 -137
- intentkit/skills/carv/token_info_and_price.py +6 -6
- intentkit/skills/casino/__init__.py +4 -15
- intentkit/skills/casino/base.py +1 -7
- intentkit/skills/casino/deck_draw.py +5 -8
- intentkit/skills/casino/deck_shuffle.py +6 -6
- intentkit/skills/casino/dice_roll.py +2 -4
- intentkit/skills/casino/schema.json +0 -1
- intentkit/skills/cdp/__init__.py +22 -84
- intentkit/skills/cdp/base.py +1 -7
- intentkit/skills/cdp/schema.json +11 -314
- intentkit/skills/chainlist/__init__.py +2 -7
- intentkit/skills/chainlist/base.py +1 -7
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/chainlist/schema.json +3 -5
- intentkit/skills/common/__init__.py +2 -9
- intentkit/skills/common/base.py +1 -7
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/common/schema.json +2 -2
- intentkit/skills/cookiefun/__init__.py +6 -9
- intentkit/skills/cookiefun/base.py +2 -7
- intentkit/skills/cookiefun/get_account_details.py +7 -7
- intentkit/skills/cookiefun/get_account_feed.py +19 -19
- intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
- intentkit/skills/cookiefun/get_sectors.py +3 -3
- intentkit/skills/cookiefun/schema.json +1 -3
- intentkit/skills/cookiefun/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/__init__.py +7 -24
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +10 -24
- intentkit/skills/cryptocompare/fetch_news.py +4 -5
- intentkit/skills/cryptocompare/fetch_price.py +6 -7
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
- intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
- intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
- intentkit/skills/cryptocompare/schema.json +3 -3
- intentkit/skills/cryptopanic/__init__.py +7 -10
- intentkit/skills/cryptopanic/base.py +51 -55
- intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
- intentkit/skills/cryptopanic/schema.json +105 -103
- intentkit/skills/dapplooker/__init__.py +2 -9
- intentkit/skills/dapplooker/base.py +4 -9
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/dapplooker/schema.json +3 -5
- intentkit/skills/defillama/__init__.py +24 -74
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +8 -19
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_block.py +6 -8
- intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
- intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
- intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
- intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
- intentkit/skills/defillama/schema.json +5 -1
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
- intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
- intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
- intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
- intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
- intentkit/skills/defillama/yields/fetch_pools.py +26 -30
- intentkit/skills/dexscreener/__init__.py +97 -102
- intentkit/skills/dexscreener/base.py +125 -130
- intentkit/skills/dexscreener/get_pair_info.py +4 -5
- intentkit/skills/dexscreener/get_token_pairs.py +4 -5
- intentkit/skills/dexscreener/get_tokens_info.py +7 -8
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/schema.json +91 -93
- intentkit/skills/dexscreener/search_token.py +182 -184
- intentkit/skills/dexscreener/utils.py +15 -14
- intentkit/skills/dune_analytics/__init__.py +7 -9
- intentkit/skills/dune_analytics/base.py +48 -52
- intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
- intentkit/skills/dune_analytics/schema.json +104 -99
- intentkit/skills/elfa/__init__.py +5 -18
- intentkit/skills/elfa/base.py +10 -14
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/schema.json +3 -2
- intentkit/skills/elfa/stats.py +4 -4
- intentkit/skills/elfa/tokens.py +12 -12
- intentkit/skills/elfa/utils.py +26 -28
- intentkit/skills/enso/__init__.py +11 -31
- intentkit/skills/enso/base.py +54 -35
- intentkit/skills/enso/best_yield.py +16 -24
- intentkit/skills/enso/networks.py +6 -11
- intentkit/skills/enso/prices.py +11 -13
- intentkit/skills/enso/route.py +34 -38
- intentkit/skills/enso/schema.json +3 -2
- intentkit/skills/enso/tokens.py +29 -38
- intentkit/skills/enso/wallet.py +76 -191
- intentkit/skills/erc20/__init__.py +50 -0
- intentkit/skills/erc20/base.py +11 -0
- intentkit/skills/erc20/erc20.svg +5 -0
- intentkit/skills/erc20/schema.json +74 -0
- intentkit/skills/erc721/__init__.py +53 -0
- intentkit/skills/erc721/base.py +11 -0
- intentkit/skills/erc721/erc721.svg +5 -0
- intentkit/skills/erc721/schema.json +90 -0
- intentkit/skills/firecrawl/__init__.py +5 -18
- intentkit/skills/firecrawl/base.py +4 -9
- intentkit/skills/firecrawl/clear.py +4 -8
- intentkit/skills/firecrawl/crawl.py +19 -19
- intentkit/skills/firecrawl/query.py +4 -3
- intentkit/skills/firecrawl/schema.json +2 -6
- intentkit/skills/firecrawl/scrape.py +17 -22
- intentkit/skills/firecrawl/utils.py +50 -42
- intentkit/skills/github/__init__.py +2 -7
- intentkit/skills/github/base.py +1 -7
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/github/schema.json +3 -4
- intentkit/skills/heurist/__init__.py +8 -27
- intentkit/skills/heurist/base.py +4 -9
- intentkit/skills/heurist/image_generation_animagine_xl.py +13 -15
- intentkit/skills/heurist/image_generation_arthemy_comics.py +13 -15
- intentkit/skills/heurist/image_generation_arthemy_real.py +13 -15
- intentkit/skills/heurist/image_generation_braindance.py +13 -15
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +13 -15
- intentkit/skills/heurist/image_generation_flux_1_dev.py +13 -15
- intentkit/skills/heurist/image_generation_sdxl.py +13 -15
- intentkit/skills/heurist/schema.json +2 -2
- intentkit/skills/http/__init__.py +4 -15
- intentkit/skills/http/base.py +1 -7
- intentkit/skills/http/get.py +21 -16
- intentkit/skills/http/post.py +23 -18
- intentkit/skills/http/put.py +23 -18
- intentkit/skills/http/schema.json +4 -5
- intentkit/skills/lifi/__init__.py +8 -13
- intentkit/skills/lifi/base.py +3 -9
- intentkit/skills/lifi/schema.json +17 -8
- intentkit/skills/lifi/token_execute.py +150 -60
- intentkit/skills/lifi/token_quote.py +8 -10
- intentkit/skills/lifi/utils.py +104 -51
- intentkit/skills/moralis/__init__.py +6 -10
- intentkit/skills/moralis/api.py +6 -7
- intentkit/skills/moralis/base.py +5 -10
- intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
- intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
- intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
- intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
- intentkit/skills/moralis/schema.json +7 -2
- intentkit/skills/morpho/__init__.py +52 -0
- intentkit/skills/morpho/base.py +11 -0
- intentkit/skills/morpho/morpho.svg +12 -0
- intentkit/skills/morpho/schema.json +73 -0
- intentkit/skills/nation/__init__.py +4 -9
- intentkit/skills/nation/base.py +5 -10
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/nation/schema.json +4 -3
- intentkit/skills/onchain.py +30 -0
- intentkit/skills/openai/__init__.py +17 -18
- intentkit/skills/openai/base.py +10 -14
- intentkit/skills/openai/dalle_image_generation.py +4 -9
- intentkit/skills/openai/gpt_avatar_generator.py +102 -0
- intentkit/skills/openai/gpt_image_generation.py +5 -9
- intentkit/skills/openai/gpt_image_mini_generator.py +92 -0
- intentkit/skills/openai/gpt_image_to_image.py +5 -9
- intentkit/skills/openai/image_to_text.py +3 -7
- intentkit/skills/openai/schema.json +34 -3
- intentkit/skills/portfolio/__init__.py +11 -35
- intentkit/skills/portfolio/base.py +33 -19
- intentkit/skills/portfolio/schema.json +3 -5
- intentkit/skills/portfolio/token_balances.py +21 -21
- intentkit/skills/portfolio/wallet_approvals.py +17 -18
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
- intentkit/skills/portfolio/wallet_history.py +31 -31
- intentkit/skills/portfolio/wallet_net_worth.py +13 -13
- intentkit/skills/portfolio/wallet_nfts.py +19 -19
- intentkit/skills/portfolio/wallet_profitability.py +18 -18
- intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
- intentkit/skills/portfolio/wallet_stats.py +3 -3
- intentkit/skills/portfolio/wallet_swaps.py +19 -19
- intentkit/skills/pyth/__init__.py +50 -0
- intentkit/skills/pyth/base.py +11 -0
- intentkit/skills/pyth/pyth.svg +6 -0
- intentkit/skills/pyth/schema.json +75 -0
- intentkit/skills/skills.toml +36 -0
- intentkit/skills/slack/__init__.py +5 -17
- intentkit/skills/slack/base.py +3 -9
- intentkit/skills/slack/get_channel.py +8 -8
- intentkit/skills/slack/get_message.py +9 -9
- intentkit/skills/slack/schedule_message.py +5 -5
- intentkit/skills/slack/schema.json +2 -2
- intentkit/skills/slack/send_message.py +3 -5
- intentkit/skills/supabase/__init__.py +7 -23
- intentkit/skills/supabase/base.py +1 -7
- intentkit/skills/supabase/delete_data.py +4 -4
- intentkit/skills/supabase/fetch_data.py +12 -12
- intentkit/skills/supabase/insert_data.py +4 -4
- intentkit/skills/supabase/invoke_function.py +6 -6
- intentkit/skills/supabase/schema.json +2 -3
- intentkit/skills/supabase/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- intentkit/skills/superfluid/__init__.py +53 -0
- intentkit/skills/superfluid/base.py +11 -0
- intentkit/skills/superfluid/schema.json +89 -0
- intentkit/skills/superfluid/superfluid.svg +6 -0
- intentkit/skills/system/__init__.py +7 -24
- intentkit/skills/system/add_autonomous_task.py +10 -12
- intentkit/skills/system/delete_autonomous_task.py +2 -2
- intentkit/skills/system/edit_autonomous_task.py +14 -18
- intentkit/skills/system/list_autonomous_tasks.py +3 -5
- intentkit/skills/system/read_agent_api_key.py +6 -4
- intentkit/skills/system/regenerate_agent_api_key.py +6 -4
- intentkit/skills/system/schema.json +6 -8
- intentkit/skills/tavily/__init__.py +3 -12
- intentkit/skills/tavily/base.py +4 -9
- intentkit/skills/tavily/schema.json +3 -5
- intentkit/skills/tavily/tavily_extract.py +2 -4
- intentkit/skills/tavily/tavily_search.py +4 -6
- intentkit/skills/token/__init__.py +5 -10
- intentkit/skills/token/base.py +7 -11
- intentkit/skills/token/erc20_transfers.py +19 -19
- intentkit/skills/token/schema.json +3 -6
- intentkit/skills/token/token_analytics.py +3 -3
- intentkit/skills/token/token_price.py +13 -13
- intentkit/skills/token/token_search.py +9 -9
- intentkit/skills/twitter/__init__.py +11 -35
- intentkit/skills/twitter/base.py +22 -34
- intentkit/skills/twitter/follow_user.py +2 -6
- intentkit/skills/twitter/get_mentions.py +5 -12
- intentkit/skills/twitter/get_timeline.py +4 -12
- intentkit/skills/twitter/get_user_by_username.py +2 -6
- intentkit/skills/twitter/get_user_tweets.py +5 -13
- intentkit/skills/twitter/like_tweet.py +2 -6
- intentkit/skills/twitter/post_tweet.py +6 -9
- intentkit/skills/twitter/reply_tweet.py +6 -9
- intentkit/skills/twitter/retweet.py +2 -6
- intentkit/skills/twitter/schema.json +1 -0
- intentkit/skills/twitter/search_tweets.py +4 -12
- intentkit/skills/unrealspeech/__init__.py +2 -7
- intentkit/skills/unrealspeech/base.py +2 -8
- intentkit/skills/unrealspeech/schema.json +2 -5
- intentkit/skills/unrealspeech/text_to_speech.py +8 -8
- intentkit/skills/venice_audio/__init__.py +98 -106
- intentkit/skills/venice_audio/base.py +117 -121
- intentkit/skills/venice_audio/input.py +41 -41
- intentkit/skills/venice_audio/schema.json +151 -152
- intentkit/skills/venice_audio/venice_audio.py +38 -21
- intentkit/skills/venice_image/__init__.py +147 -154
- intentkit/skills/venice_image/api.py +138 -138
- intentkit/skills/venice_image/base.py +185 -192
- intentkit/skills/venice_image/config.py +33 -35
- intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
- intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
- intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
- intentkit/skills/venice_image/image_generation/image_generation_base.py +11 -10
- intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
- intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
- intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
- intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
- intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
- intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
- intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
- intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
- intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
- intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
- intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
- intentkit/skills/venice_image/schema.json +267 -267
- intentkit/skills/venice_image/utils.py +77 -78
- intentkit/skills/web_scraper/__init__.py +5 -18
- intentkit/skills/web_scraper/base.py +21 -7
- intentkit/skills/web_scraper/document_indexer.py +7 -6
- intentkit/skills/web_scraper/schema.json +2 -6
- intentkit/skills/web_scraper/scrape_and_index.py +15 -15
- intentkit/skills/web_scraper/utils.py +62 -63
- intentkit/skills/web_scraper/website_indexer.py +17 -19
- intentkit/skills/weth/__init__.py +49 -0
- intentkit/skills/weth/base.py +11 -0
- intentkit/skills/weth/schema.json +58 -0
- intentkit/skills/weth/weth.svg +6 -0
- intentkit/skills/wow/__init__.py +51 -0
- intentkit/skills/wow/base.py +11 -0
- intentkit/skills/wow/schema.json +89 -0
- intentkit/skills/wow/wow.svg +7 -0
- intentkit/skills/x402/__init__.py +58 -0
- intentkit/skills/x402/base.py +99 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +40 -0
- intentkit/skills/x402/x402.webp +0 -0
- intentkit/skills/xmtp/__init__.py +4 -15
- intentkit/skills/xmtp/base.py +5 -5
- intentkit/skills/xmtp/price.py +7 -6
- intentkit/skills/xmtp/schema.json +69 -71
- intentkit/skills/xmtp/swap.py +6 -8
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/__init__.py +4 -0
- intentkit/utils/chain.py +198 -96
- intentkit/utils/ens.py +135 -0
- intentkit/utils/error.py +5 -2
- intentkit/utils/logging.py +9 -11
- intentkit/utils/schema.py +100 -0
- intentkit/utils/slack_alert.py +8 -8
- intentkit/utils/tx.py +16 -8
- intentkit/uv.lock +3377 -0
- {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/METADATA +13 -15
- intentkit-0.8.34.dev7.dist-info/RECORD +478 -0
- intentkit-0.8.34.dev7.dist-info/licenses/LICENSE +21 -0
- intentkit/core/node.py +0 -215
- intentkit/models/conversation.py +0 -286
- intentkit/models/generator.py +0 -347
- intentkit/skills/cdp/get_balance.py +0 -110
- intentkit/skills/cdp/swap.py +0 -121
- intentkit/skills/moralis/tests/__init__.py +0 -0
- intentkit/skills/moralis/tests/test_wallet.py +0 -511
- intentkit-0.7.5.dev3.dist-info/RECORD +0 -424
- {intentkit-0.7.5.dev3.dist-info/licenses → intentkit}/LICENSE +0 -0
- {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/WHEEL +0 -0
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
"""Tests for the Moralis Wallet Portfolio skills."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import json
|
|
5
|
-
import unittest
|
|
6
|
-
from unittest.mock import AsyncMock, MagicMock, patch
|
|
7
|
-
|
|
8
|
-
from intentkit.skills.moralis import (
|
|
9
|
-
FetchChainPortfolio,
|
|
10
|
-
FetchSolanaPortfolio,
|
|
11
|
-
FetchWalletPortfolio,
|
|
12
|
-
get_skills,
|
|
13
|
-
)
|
|
14
|
-
from intentkit.skills.moralis.api import (
|
|
15
|
-
fetch_moralis_data,
|
|
16
|
-
fetch_wallet_balances,
|
|
17
|
-
get_solana_portfolio,
|
|
18
|
-
)
|
|
19
|
-
from intentkit.skills.moralis.base import WalletBaseTool
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class DummyResponse:
|
|
23
|
-
"""Mock HTTP response for testing."""
|
|
24
|
-
|
|
25
|
-
def __init__(self, status_code, json_data):
|
|
26
|
-
self.status_code = status_code
|
|
27
|
-
self._json_data = json_data
|
|
28
|
-
self.text = json.dumps(json_data) if json_data else ""
|
|
29
|
-
|
|
30
|
-
def json(self):
|
|
31
|
-
return self._json_data
|
|
32
|
-
|
|
33
|
-
async def raise_for_status(self):
|
|
34
|
-
if self.status_code >= 400:
|
|
35
|
-
raise Exception(f"HTTP Error: {self.status_code}")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class TestWalletBaseClass(unittest.TestCase):
|
|
39
|
-
"""Test the base wallet portfolio tool class."""
|
|
40
|
-
|
|
41
|
-
def setUp(self):
|
|
42
|
-
self.loop = asyncio.new_event_loop()
|
|
43
|
-
asyncio.set_event_loop(self.loop)
|
|
44
|
-
|
|
45
|
-
self.mock_skill_store = MagicMock()
|
|
46
|
-
|
|
47
|
-
def tearDown(self):
|
|
48
|
-
self.loop.close()
|
|
49
|
-
|
|
50
|
-
def test_base_class_init(self):
|
|
51
|
-
"""Test base class initialization."""
|
|
52
|
-
|
|
53
|
-
# Create a concrete subclass for testing
|
|
54
|
-
class TestTool(WalletBaseTool):
|
|
55
|
-
async def _arun(self, *args, **kwargs):
|
|
56
|
-
return "test"
|
|
57
|
-
|
|
58
|
-
tool = TestTool(
|
|
59
|
-
name="test_tool",
|
|
60
|
-
description="Test tool",
|
|
61
|
-
args_schema=MagicMock(),
|
|
62
|
-
api_key="test_key",
|
|
63
|
-
skill_store=self.mock_skill_store,
|
|
64
|
-
agent_id="test_agent",
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
self.assertEqual(tool.api_key, "test_key")
|
|
68
|
-
self.assertEqual(tool.agent_id, "test_agent")
|
|
69
|
-
self.assertEqual(tool.skill_store, self.mock_skill_store)
|
|
70
|
-
self.assertEqual(tool.category, "moralis")
|
|
71
|
-
|
|
72
|
-
def test_get_chain_name(self):
|
|
73
|
-
"""Test chain name conversion."""
|
|
74
|
-
|
|
75
|
-
class TestTool(WalletBaseTool):
|
|
76
|
-
async def _arun(self, *args, **kwargs):
|
|
77
|
-
return "test"
|
|
78
|
-
|
|
79
|
-
tool = TestTool(
|
|
80
|
-
name="test_tool",
|
|
81
|
-
description="Test tool",
|
|
82
|
-
args_schema=MagicMock(),
|
|
83
|
-
api_key="test_key",
|
|
84
|
-
skill_store=self.mock_skill_store,
|
|
85
|
-
agent_id="test_agent",
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
# Test with known chain IDs
|
|
89
|
-
self.assertEqual(tool._get_chain_name(1), "eth")
|
|
90
|
-
self.assertEqual(tool._get_chain_name(56), "bsc")
|
|
91
|
-
self.assertEqual(tool._get_chain_name(137), "polygon")
|
|
92
|
-
|
|
93
|
-
# Test with unknown chain ID
|
|
94
|
-
self.assertEqual(tool._get_chain_name(999999), "eth")
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
class TestAPIFunctions(unittest.IsolatedAsyncioTestCase):
|
|
98
|
-
"""Test the API interaction functions."""
|
|
99
|
-
|
|
100
|
-
async def test_fetch_moralis_data(self):
|
|
101
|
-
"""Test the base Moralis API function."""
|
|
102
|
-
with patch("httpx.AsyncClient") as MockClient:
|
|
103
|
-
client_instance = AsyncMock()
|
|
104
|
-
client_instance.get.return_value = DummyResponse(
|
|
105
|
-
200, {"success": True, "data": "test_data"}
|
|
106
|
-
)
|
|
107
|
-
MockClient.return_value.__aenter__.return_value = client_instance
|
|
108
|
-
|
|
109
|
-
result = await fetch_moralis_data(
|
|
110
|
-
"test_api_key", "test_endpoint", "0xAddress", 1
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
self.assertEqual(result, {"success": True, "data": "test_data"})
|
|
114
|
-
|
|
115
|
-
# Test error handling
|
|
116
|
-
client_instance.get.return_value = DummyResponse(404, None)
|
|
117
|
-
client_instance.get.return_value.raise_for_status = AsyncMock(
|
|
118
|
-
side_effect=Exception("HTTP error 404")
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
result = await fetch_moralis_data(
|
|
122
|
-
"test_api_key", "test_endpoint", "0xAddress", 1
|
|
123
|
-
)
|
|
124
|
-
self.assertIn("error", result)
|
|
125
|
-
|
|
126
|
-
async def test_fetch_wallet_balances(self):
|
|
127
|
-
"""Test fetching wallet balances."""
|
|
128
|
-
with patch("skills.moralis.api.fetch_moralis_data") as mock_fetch:
|
|
129
|
-
mock_fetch.return_value = {
|
|
130
|
-
"result": [
|
|
131
|
-
{
|
|
132
|
-
"token_address": "0x123",
|
|
133
|
-
"symbol": "TEST",
|
|
134
|
-
"balance": "1000000",
|
|
135
|
-
"usd_value": 100,
|
|
136
|
-
}
|
|
137
|
-
]
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
result = await fetch_wallet_balances("test_api_key", "0xAddress", 1)
|
|
141
|
-
|
|
142
|
-
self.assertEqual(result["result"][0]["symbol"], "TEST")
|
|
143
|
-
mock_fetch.assert_called_once_with(
|
|
144
|
-
"test_api_key", "wallets/{address}/tokens", "0xAddress", 1, None
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
async def test_get_solana_portfolio(self):
|
|
148
|
-
"""Test getting Solana portfolio."""
|
|
149
|
-
with patch("skills.moralis.api.fetch_solana_api") as mock_fetch:
|
|
150
|
-
mock_fetch.return_value = {
|
|
151
|
-
"nativeBalance": {"solana": 1.5, "lamports": 1500000000},
|
|
152
|
-
"tokens": [
|
|
153
|
-
{
|
|
154
|
-
"symbol": "TEST",
|
|
155
|
-
"name": "Test Token",
|
|
156
|
-
"mint": "TokenMintAddress",
|
|
157
|
-
"associatedTokenAddress": "AssocTokenAddress",
|
|
158
|
-
"amount": 10,
|
|
159
|
-
"decimals": 9,
|
|
160
|
-
"amountRaw": "10000000000",
|
|
161
|
-
}
|
|
162
|
-
],
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
result = await get_solana_portfolio("test_api_key", "SolAddress", "mainnet")
|
|
166
|
-
|
|
167
|
-
mock_fetch.assert_called_once_with(
|
|
168
|
-
"test_api_key", "/account/mainnet/SolAddress/portfolio"
|
|
169
|
-
)
|
|
170
|
-
self.assertEqual(result["nativeBalance"]["solana"], 1.5)
|
|
171
|
-
self.assertEqual(len(result["tokens"]), 1)
|
|
172
|
-
self.assertEqual(result["tokens"][0]["symbol"], "TEST")
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
class TestFetchWalletPortfolio(unittest.IsolatedAsyncioTestCase):
|
|
176
|
-
"""Test the FetchWalletPortfolio skill."""
|
|
177
|
-
|
|
178
|
-
async def test_wallet_portfolio_success(self):
|
|
179
|
-
"""Test successful wallet portfolio fetch."""
|
|
180
|
-
mock_skill_store = MagicMock()
|
|
181
|
-
|
|
182
|
-
with (
|
|
183
|
-
patch(
|
|
184
|
-
"skills.moralis.moralis_fetch_wallet_portfolio.fetch_wallet_balances"
|
|
185
|
-
) as mock_balances,
|
|
186
|
-
patch(
|
|
187
|
-
"skills.moralis.moralis_fetch_wallet_portfolio.fetch_net_worth"
|
|
188
|
-
) as mock_net_worth,
|
|
189
|
-
):
|
|
190
|
-
# Mock successful responses
|
|
191
|
-
mock_balances.return_value = {
|
|
192
|
-
"result": [
|
|
193
|
-
{
|
|
194
|
-
"token_address": "0x123",
|
|
195
|
-
"symbol": "TEST",
|
|
196
|
-
"name": "Test Token",
|
|
197
|
-
"balance": "1000000000000000000",
|
|
198
|
-
"balance_formatted": "1.0",
|
|
199
|
-
"usd_value": 100,
|
|
200
|
-
}
|
|
201
|
-
]
|
|
202
|
-
}
|
|
203
|
-
mock_net_worth.return_value = {"result": {"total_networth_usd": 1000}}
|
|
204
|
-
|
|
205
|
-
tool = FetchWalletPortfolio(
|
|
206
|
-
name="fetch_wallet_portfolio",
|
|
207
|
-
description="Test description",
|
|
208
|
-
args_schema=MagicMock(),
|
|
209
|
-
api_key="test_key",
|
|
210
|
-
skill_store=mock_skill_store,
|
|
211
|
-
agent_id="test_agent",
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
result = await tool._arun(address="0xAddress")
|
|
215
|
-
|
|
216
|
-
self.assertEqual(result.address, "0xAddress")
|
|
217
|
-
self.assertEqual(result.total_net_worth, 1000)
|
|
218
|
-
self.assertEqual(len(result.tokens), 1)
|
|
219
|
-
self.assertEqual(result.tokens[0].symbol, "TEST")
|
|
220
|
-
|
|
221
|
-
async def test_wallet_portfolio_with_solana(self):
|
|
222
|
-
"""Test wallet portfolio with Solana support."""
|
|
223
|
-
mock_skill_store = MagicMock()
|
|
224
|
-
|
|
225
|
-
with (
|
|
226
|
-
patch(
|
|
227
|
-
"skills.moralis.moralis_fetch_wallet_portfolio.fetch_wallet_balances"
|
|
228
|
-
) as mock_evm_balances,
|
|
229
|
-
patch(
|
|
230
|
-
"skills.moralis.moralis_fetch_wallet_portfolio.fetch_net_worth"
|
|
231
|
-
) as mock_net_worth,
|
|
232
|
-
patch(
|
|
233
|
-
"skills.moralis.moralis_fetch_wallet_portfolio.get_solana_portfolio"
|
|
234
|
-
) as mock_sol_portfolio,
|
|
235
|
-
patch(
|
|
236
|
-
"skills.moralis.moralis_fetch_wallet_portfolio.get_token_price"
|
|
237
|
-
) as mock_token_price,
|
|
238
|
-
):
|
|
239
|
-
# Mock EVM responses
|
|
240
|
-
mock_evm_balances.return_value = {
|
|
241
|
-
"result": [
|
|
242
|
-
{
|
|
243
|
-
"token_address": "0x123",
|
|
244
|
-
"symbol": "ETH",
|
|
245
|
-
"name": "Ethereum",
|
|
246
|
-
"balance": "1000000000000000000",
|
|
247
|
-
"balance_formatted": "1.0",
|
|
248
|
-
"usd_value": 2000,
|
|
249
|
-
}
|
|
250
|
-
]
|
|
251
|
-
}
|
|
252
|
-
mock_net_worth.return_value = {"result": {"total_networth_usd": 3000}}
|
|
253
|
-
|
|
254
|
-
# Mock Solana responses
|
|
255
|
-
mock_sol_portfolio.return_value = {
|
|
256
|
-
"nativeBalance": {"solana": 2.0, "lamports": 2000000000},
|
|
257
|
-
"tokens": [
|
|
258
|
-
{
|
|
259
|
-
"symbol": "SOL",
|
|
260
|
-
"name": "Solana",
|
|
261
|
-
"mint": "So11111111111111111111111111111111111111112",
|
|
262
|
-
"associatedTokenAddress": "AssocTokenAddress",
|
|
263
|
-
"amount": 2.0,
|
|
264
|
-
"decimals": 9,
|
|
265
|
-
"amountRaw": "2000000000",
|
|
266
|
-
}
|
|
267
|
-
],
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
mock_token_price.return_value = {"usdPrice": 500}
|
|
271
|
-
|
|
272
|
-
tool = FetchWalletPortfolio(
|
|
273
|
-
name="fetch_wallet_portfolio",
|
|
274
|
-
description="Test description",
|
|
275
|
-
args_schema=MagicMock(),
|
|
276
|
-
api_key="test_key",
|
|
277
|
-
skill_store=mock_skill_store,
|
|
278
|
-
agent_id="test_agent",
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
result = await tool._arun(address="0xAddress", include_solana=True)
|
|
282
|
-
|
|
283
|
-
self.assertEqual(result.address, "0xAddress")
|
|
284
|
-
self.assertEqual(
|
|
285
|
-
result.total_net_worth, 3000
|
|
286
|
-
) # Using the net worth from mock
|
|
287
|
-
self.assertIn("eth", result.chains)
|
|
288
|
-
self.assertIn("solana", result.chains)
|
|
289
|
-
|
|
290
|
-
# Check that we have both EVM and Solana tokens
|
|
291
|
-
token_symbols = [token.symbol for token in result.tokens]
|
|
292
|
-
self.assertIn("ETH", token_symbols)
|
|
293
|
-
self.assertIn("SOL", token_symbols)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
class TestFetchSolanaPortfolio(unittest.IsolatedAsyncioTestCase):
|
|
297
|
-
"""Test the FetchSolanaPortfolio skill."""
|
|
298
|
-
|
|
299
|
-
async def test_solana_portfolio_success(self):
|
|
300
|
-
"""Test successful Solana portfolio fetch."""
|
|
301
|
-
mock_skill_store = MagicMock()
|
|
302
|
-
|
|
303
|
-
with (
|
|
304
|
-
patch(
|
|
305
|
-
"skills.moralis.moralis_fetch_solana_portfolio.get_solana_portfolio"
|
|
306
|
-
) as mock_portfolio,
|
|
307
|
-
patch(
|
|
308
|
-
"skills.moralis.moralis_fetch_solana_portfolio.get_solana_nfts"
|
|
309
|
-
) as mock_nfts,
|
|
310
|
-
patch(
|
|
311
|
-
"skills.moralis.moralis_fetch_solana_portfolio.get_token_price"
|
|
312
|
-
) as mock_token_price,
|
|
313
|
-
):
|
|
314
|
-
# Mock successful responses
|
|
315
|
-
mock_portfolio.return_value = {
|
|
316
|
-
"nativeBalance": {"solana": 1.5, "lamports": 1500000000},
|
|
317
|
-
"tokens": [
|
|
318
|
-
{
|
|
319
|
-
"symbol": "TEST",
|
|
320
|
-
"name": "Test Token",
|
|
321
|
-
"mint": "TokenMintAddress",
|
|
322
|
-
"associatedTokenAddress": "AssocTokenAddress",
|
|
323
|
-
"amount": 10,
|
|
324
|
-
"decimals": 9,
|
|
325
|
-
"amountRaw": "10000000000",
|
|
326
|
-
}
|
|
327
|
-
],
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
mock_nfts.return_value = [
|
|
331
|
-
{
|
|
332
|
-
"mint": "NFTMintAddress",
|
|
333
|
-
"name": "Test NFT",
|
|
334
|
-
"symbol": "TNFT",
|
|
335
|
-
"associatedTokenAddress": "AssocTokenAddress",
|
|
336
|
-
"metadata": {"name": "Test NFT", "image": "image.png"},
|
|
337
|
-
}
|
|
338
|
-
]
|
|
339
|
-
|
|
340
|
-
mock_token_price.return_value = {"usdPrice": 25}
|
|
341
|
-
|
|
342
|
-
tool = FetchSolanaPortfolio(
|
|
343
|
-
name="fetch_solana_portfolio",
|
|
344
|
-
description="Test description",
|
|
345
|
-
args_schema=MagicMock(),
|
|
346
|
-
api_key="test_key",
|
|
347
|
-
skill_store=mock_skill_store,
|
|
348
|
-
agent_id="test_agent",
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
result = await tool._arun(address="SolanaAddress", include_nfts=True)
|
|
352
|
-
|
|
353
|
-
self.assertEqual(result.address, "SolanaAddress")
|
|
354
|
-
self.assertEqual(result.sol_balance, 1.5)
|
|
355
|
-
self.assertEqual(len(result.tokens), 1)
|
|
356
|
-
self.assertEqual(result.tokens[0].token_info.symbol, "TEST")
|
|
357
|
-
self.assertEqual(len(result.nfts), 1)
|
|
358
|
-
self.assertEqual(result.nfts[0].name, "Test NFT")
|
|
359
|
-
self.assertEqual(result.sol_price_usd, 25)
|
|
360
|
-
self.assertEqual(result.sol_value_usd, 37.5) # 1.5 SOL * $25
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
class TestFetchChainPortfolio(unittest.IsolatedAsyncioTestCase):
|
|
364
|
-
"""Test the FetchChainPortfolio skill."""
|
|
365
|
-
|
|
366
|
-
async def test_chain_portfolio_success(self):
|
|
367
|
-
"""Test successful chain portfolio fetch."""
|
|
368
|
-
mock_skill_store = MagicMock()
|
|
369
|
-
|
|
370
|
-
with patch(
|
|
371
|
-
"skills.moralis.moralis_fetch_chain_portfolio.fetch_wallet_balances"
|
|
372
|
-
) as mock_balances:
|
|
373
|
-
# Mock successful responses
|
|
374
|
-
mock_balances.return_value = {
|
|
375
|
-
"result": [
|
|
376
|
-
{
|
|
377
|
-
"token_address": "0x123",
|
|
378
|
-
"symbol": "ETH",
|
|
379
|
-
"name": "Ethereum",
|
|
380
|
-
"logo": "logo.png",
|
|
381
|
-
"decimals": 18,
|
|
382
|
-
"balance": "1000000000000000000",
|
|
383
|
-
"balance_formatted": "1.0",
|
|
384
|
-
"usd_value": 2000,
|
|
385
|
-
"native_token": True,
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
"token_address": "0x456",
|
|
389
|
-
"symbol": "TOKEN",
|
|
390
|
-
"name": "Test Token",
|
|
391
|
-
"logo": "logo2.png",
|
|
392
|
-
"decimals": 18,
|
|
393
|
-
"balance": "2000000000000000000",
|
|
394
|
-
"balance_formatted": "2.0",
|
|
395
|
-
"usd_value": 200,
|
|
396
|
-
"native_token": False,
|
|
397
|
-
},
|
|
398
|
-
]
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
tool = FetchChainPortfolio(
|
|
402
|
-
name="fetch_chain_portfolio",
|
|
403
|
-
description="Test description",
|
|
404
|
-
args_schema=MagicMock(),
|
|
405
|
-
api_key="test_key",
|
|
406
|
-
skill_store=mock_skill_store,
|
|
407
|
-
agent_id="test_agent",
|
|
408
|
-
)
|
|
409
|
-
|
|
410
|
-
result = await tool._arun(address="0xAddress", chain_id=1)
|
|
411
|
-
|
|
412
|
-
self.assertEqual(result.address, "0xAddress")
|
|
413
|
-
self.assertEqual(result.chain_id, 1)
|
|
414
|
-
self.assertEqual(result.chain_name, "eth")
|
|
415
|
-
self.assertEqual(result.total_usd_value, 2200) # 2000 + 200
|
|
416
|
-
self.assertEqual(len(result.tokens), 1) # Regular tokens, not native
|
|
417
|
-
self.assertIsNotNone(result.native_token)
|
|
418
|
-
self.assertEqual(result.native_token.symbol, "ETH")
|
|
419
|
-
self.assertEqual(result.tokens[0].symbol, "TOKEN")
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
class TestSkillInitialization(unittest.TestCase):
|
|
423
|
-
"""Test skill initialization and configuration."""
|
|
424
|
-
|
|
425
|
-
def setUp(self):
|
|
426
|
-
self.mock_skill_store = MagicMock()
|
|
427
|
-
|
|
428
|
-
def test_get_skills(self):
|
|
429
|
-
"""Test getting multiple skills from config."""
|
|
430
|
-
config = {
|
|
431
|
-
"api_key": "test_api_key",
|
|
432
|
-
"states": {
|
|
433
|
-
"fetch_wallet_portfolio": "public",
|
|
434
|
-
"fetch_chain_portfolio": "public",
|
|
435
|
-
"fetch_nft_portfolio": "private",
|
|
436
|
-
"fetch_transaction_history": "private",
|
|
437
|
-
"fetch_solana_portfolio": "public",
|
|
438
|
-
},
|
|
439
|
-
"supported_chains": {"evm": True, "solana": True},
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
# Test with mock implementation
|
|
443
|
-
with patch("skills.moralis.base.WalletBaseTool") as mock_tool:
|
|
444
|
-
mock_tool.return_value = MagicMock()
|
|
445
|
-
|
|
446
|
-
# This is just a test structure - actual implementation would create the skills
|
|
447
|
-
skills = get_skills(
|
|
448
|
-
config,
|
|
449
|
-
is_private=False, # Only get public skills
|
|
450
|
-
skill_store=self.mock_skill_store,
|
|
451
|
-
agent_id="test_agent",
|
|
452
|
-
)
|
|
453
|
-
|
|
454
|
-
# In a real implementation, we'd test that the correct skills were returned
|
|
455
|
-
# For now, we just verify the function exists
|
|
456
|
-
self.assertIsNotNone(skills)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
class TestIntegration(unittest.TestCase):
|
|
460
|
-
"""Integration tests for wallet skills."""
|
|
461
|
-
|
|
462
|
-
def test_wallet_skill_configuration(self):
|
|
463
|
-
"""Test wallet skill configuration in agent config."""
|
|
464
|
-
# Example agent configuration
|
|
465
|
-
agent_config = {
|
|
466
|
-
"id": "crypto-agent",
|
|
467
|
-
"skills": {
|
|
468
|
-
"moralis": {
|
|
469
|
-
"api_key": "test_api_key",
|
|
470
|
-
"states": {
|
|
471
|
-
"fetch_wallet_portfolio": "public",
|
|
472
|
-
"fetch_chain_portfolio": "public",
|
|
473
|
-
"fetch_nft_portfolio": "private",
|
|
474
|
-
"fetch_transaction_history": "private",
|
|
475
|
-
"fetch_solana_portfolio": "public",
|
|
476
|
-
},
|
|
477
|
-
"supported_chains": {"evm": True, "solana": True},
|
|
478
|
-
}
|
|
479
|
-
},
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
# Verify the configuration structure is valid
|
|
483
|
-
moralis_config = agent_config["skills"]["moralis"]
|
|
484
|
-
self.assertIn("api_key", moralis_config)
|
|
485
|
-
self.assertIn("states", moralis_config)
|
|
486
|
-
self.assertIn("supported_chains", moralis_config)
|
|
487
|
-
|
|
488
|
-
# Check that all required skills are configured
|
|
489
|
-
states = moralis_config["states"]
|
|
490
|
-
required_skills = [
|
|
491
|
-
"fetch_wallet_portfolio",
|
|
492
|
-
"fetch_chain_portfolio",
|
|
493
|
-
"fetch_nft_portfolio",
|
|
494
|
-
"fetch_transaction_history",
|
|
495
|
-
"fetch_solana_portfolio",
|
|
496
|
-
]
|
|
497
|
-
|
|
498
|
-
for skill in required_skills:
|
|
499
|
-
self.assertIn(skill, states)
|
|
500
|
-
self.assertIn(states[skill], ["public", "private", "disabled"])
|
|
501
|
-
|
|
502
|
-
# Check chain configuration
|
|
503
|
-
chains = moralis_config["supported_chains"]
|
|
504
|
-
self.assertIn("evm", chains)
|
|
505
|
-
self.assertIn("solana", chains)
|
|
506
|
-
self.assertTrue(isinstance(chains["evm"], bool))
|
|
507
|
-
self.assertTrue(isinstance(chains["solana"], bool))
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if __name__ == "__main__":
|
|
511
|
-
unittest.main()
|