intentkit 0.8.16.dev1__py3-none-any.whl → 0.8.17.dev2__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 +1 -1
- intentkit/abstracts/agent.py +4 -5
- intentkit/abstracts/engine.py +5 -5
- intentkit/abstracts/graph.py +6 -5
- intentkit/abstracts/skill.py +5 -5
- intentkit/abstracts/twitter.py +4 -5
- intentkit/clients/cdp.py +19 -77
- intentkit/clients/twitter.py +26 -34
- intentkit/clients/web3.py +1 -3
- intentkit/config/config.py +4 -0
- intentkit/core/agent.py +15 -15
- intentkit/core/asset.py +1 -2
- intentkit/core/client.py +1 -1
- intentkit/core/credit.py +19 -20
- intentkit/core/engine.py +2 -4
- intentkit/core/node.py +2 -1
- intentkit/core/prompt.py +3 -4
- intentkit/core/scheduler.py +1 -1
- intentkit/core/statistics.py +6 -7
- intentkit/models/agent.py +125 -92
- intentkit/models/agent_data.py +62 -36
- intentkit/models/app_setting.py +6 -6
- intentkit/models/chat.py +27 -24
- intentkit/models/conversation.py +8 -8
- intentkit/models/credit.py +62 -64
- intentkit/models/db.py +8 -7
- intentkit/models/db_mig.py +2 -2
- intentkit/models/llm.py +12 -14
- intentkit/models/redis.py +2 -3
- intentkit/models/skill.py +25 -27
- intentkit/models/skills.csv +29 -28
- intentkit/models/user.py +21 -22
- intentkit/skills/acolyt/ask.py +3 -4
- intentkit/skills/acolyt/base.py +1 -3
- intentkit/skills/aixbt/base.py +1 -3
- intentkit/skills/aixbt/projects.py +13 -13
- intentkit/skills/allora/base.py +1 -3
- intentkit/skills/allora/price.py +2 -3
- intentkit/skills/base.py +15 -22
- intentkit/skills/basename/__init__.py +3 -5
- intentkit/skills/carv/__init__.py +7 -8
- intentkit/skills/carv/base.py +6 -6
- intentkit/skills/carv/fetch_news.py +3 -3
- intentkit/skills/carv/onchain_query.py +4 -4
- intentkit/skills/carv/token_info_and_price.py +5 -5
- intentkit/skills/casino/base.py +1 -3
- intentkit/skills/casino/deck_draw.py +1 -2
- intentkit/skills/casino/deck_shuffle.py +1 -2
- intentkit/skills/casino/dice_roll.py +1 -2
- intentkit/skills/cdp/__init__.py +3 -5
- intentkit/skills/cdp/base.py +1 -3
- intentkit/skills/chainlist/base.py +1 -3
- intentkit/skills/chainlist/chain_lookup.py +18 -18
- intentkit/skills/common/base.py +1 -3
- intentkit/skills/common/current_time.py +1 -2
- intentkit/skills/cookiefun/base.py +1 -2
- 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/search_accounts.py +9 -9
- intentkit/skills/cryptocompare/api.py +2 -3
- intentkit/skills/cryptocompare/base.py +6 -6
- intentkit/skills/cryptocompare/fetch_news.py +3 -4
- intentkit/skills/cryptocompare/fetch_price.py +5 -6
- intentkit/skills/cryptocompare/fetch_top_exchanges.py +3 -4
- intentkit/skills/cryptocompare/fetch_top_market_cap.py +3 -4
- intentkit/skills/cryptocompare/fetch_top_volume.py +3 -4
- intentkit/skills/cryptocompare/fetch_trading_signals.py +4 -5
- intentkit/skills/cryptopanic/__init__.py +4 -4
- intentkit/skills/cryptopanic/base.py +1 -3
- intentkit/skills/cryptopanic/fetch_crypto_news.py +3 -5
- intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +3 -3
- intentkit/skills/dapplooker/base.py +1 -3
- intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
- intentkit/skills/defillama/api.py +6 -9
- intentkit/skills/defillama/base.py +5 -6
- intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +6 -8
- intentkit/skills/defillama/coins/fetch_block.py +4 -6
- intentkit/skills/defillama/coins/fetch_current_prices.py +6 -8
- intentkit/skills/defillama/coins/fetch_first_price.py +5 -7
- intentkit/skills/defillama/coins/fetch_historical_prices.py +7 -9
- intentkit/skills/defillama/coins/fetch_price_chart.py +7 -9
- intentkit/skills/defillama/coins/fetch_price_percentage.py +5 -7
- intentkit/skills/defillama/config/chains.py +1 -3
- intentkit/skills/defillama/fees/fetch_fees_overview.py +22 -24
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +14 -16
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +6 -8
- intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +3 -5
- intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +5 -7
- intentkit/skills/defillama/tests/api_integration.test.py +1 -1
- intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +2 -4
- intentkit/skills/defillama/tvl/fetch_chains.py +7 -9
- intentkit/skills/defillama/tvl/fetch_historical_tvl.py +2 -4
- intentkit/skills/defillama/tvl/fetch_protocol.py +30 -36
- intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +1 -3
- intentkit/skills/defillama/tvl/fetch_protocols.py +35 -43
- intentkit/skills/defillama/volumes/fetch_dex_overview.py +40 -46
- intentkit/skills/defillama/volumes/fetch_dex_summary.py +33 -35
- intentkit/skills/defillama/volumes/fetch_options_overview.py +22 -26
- intentkit/skills/defillama/yields/fetch_pool_chart.py +8 -10
- intentkit/skills/defillama/yields/fetch_pools.py +24 -28
- intentkit/skills/dexscreener/__init__.py +2 -2
- intentkit/skills/dexscreener/base.py +3 -3
- intentkit/skills/dexscreener/get_pair_info.py +2 -2
- intentkit/skills/dexscreener/get_token_pairs.py +2 -2
- intentkit/skills/dexscreener/get_tokens_info.py +5 -5
- intentkit/skills/dexscreener/model/search_token_response.py +80 -82
- intentkit/skills/dexscreener/search_token.py +182 -182
- intentkit/skills/dexscreener/utils.py +15 -14
- intentkit/skills/dune_analytics/__init__.py +4 -4
- intentkit/skills/dune_analytics/base.py +1 -3
- intentkit/skills/dune_analytics/fetch_kol_buys.py +4 -4
- intentkit/skills/dune_analytics/fetch_nation_metrics.py +5 -5
- intentkit/skills/elfa/base.py +1 -3
- intentkit/skills/elfa/mention.py +19 -21
- intentkit/skills/elfa/stats.py +4 -4
- intentkit/skills/elfa/tokens.py +12 -12
- intentkit/skills/elfa/utils.py +25 -27
- intentkit/skills/enso/__init__.py +2 -2
- intentkit/skills/enso/base.py +5 -8
- intentkit/skills/enso/best_yield.py +4 -6
- intentkit/skills/enso/networks.py +1 -2
- intentkit/skills/enso/prices.py +1 -3
- intentkit/skills/enso/route.py +1 -3
- intentkit/skills/enso/tokens.py +1 -3
- intentkit/skills/enso/wallet.py +5 -5
- intentkit/skills/erc20/__init__.py +4 -6
- intentkit/skills/erc721/__init__.py +4 -6
- intentkit/skills/firecrawl/base.py +1 -3
- intentkit/skills/firecrawl/clear.py +1 -2
- intentkit/skills/firecrawl/crawl.py +9 -10
- intentkit/skills/firecrawl/query.py +1 -2
- intentkit/skills/firecrawl/scrape.py +7 -8
- intentkit/skills/firecrawl/utils.py +13 -13
- intentkit/skills/github/base.py +1 -3
- intentkit/skills/github/github_search.py +1 -2
- intentkit/skills/heurist/base.py +1 -3
- intentkit/skills/heurist/image_generation_animagine_xl.py +7 -8
- intentkit/skills/heurist/image_generation_arthemy_comics.py +7 -8
- intentkit/skills/heurist/image_generation_arthemy_real.py +7 -8
- intentkit/skills/heurist/image_generation_braindance.py +7 -8
- intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +7 -8
- intentkit/skills/heurist/image_generation_flux_1_dev.py +7 -8
- intentkit/skills/heurist/image_generation_sdxl.py +7 -8
- intentkit/skills/http/base.py +1 -3
- intentkit/skills/http/get.py +7 -7
- intentkit/skills/http/post.py +9 -9
- intentkit/skills/http/put.py +9 -9
- intentkit/skills/lifi/__init__.py +4 -4
- intentkit/skills/lifi/base.py +1 -3
- intentkit/skills/lifi/token_execute.py +13 -13
- intentkit/skills/lifi/token_quote.py +6 -6
- intentkit/skills/lifi/utils.py +16 -16
- intentkit/skills/moralis/__init__.py +3 -3
- intentkit/skills/moralis/api.py +6 -7
- intentkit/skills/moralis/base.py +2 -4
- 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/morpho/__init__.py +4 -6
- intentkit/skills/nation/__init__.py +2 -2
- intentkit/skills/nation/base.py +1 -3
- intentkit/skills/nation/nft_check.py +3 -4
- intentkit/skills/onchain.py +2 -6
- intentkit/skills/openai/base.py +1 -3
- intentkit/skills/openai/dalle_image_generation.py +1 -3
- intentkit/skills/openai/gpt_image_generation.py +2 -3
- intentkit/skills/openai/gpt_image_to_image.py +2 -3
- intentkit/skills/openai/image_to_text.py +1 -2
- intentkit/skills/portfolio/base.py +6 -6
- intentkit/skills/portfolio/token_balances.py +21 -21
- intentkit/skills/portfolio/wallet_approvals.py +7 -7
- intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
- intentkit/skills/portfolio/wallet_history.py +21 -21
- intentkit/skills/portfolio/wallet_net_worth.py +13 -13
- intentkit/skills/portfolio/wallet_nfts.py +19 -19
- intentkit/skills/portfolio/wallet_profitability.py +7 -7
- 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 +3 -5
- intentkit/skills/slack/base.py +2 -4
- 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/send_message.py +3 -5
- intentkit/skills/supabase/base.py +1 -3
- 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/update_data.py +6 -6
- intentkit/skills/supabase/upsert_data.py +4 -4
- intentkit/skills/superfluid/__init__.py +4 -6
- intentkit/skills/system/add_autonomous_task.py +8 -10
- intentkit/skills/system/edit_autonomous_task.py +12 -14
- intentkit/skills/system/list_autonomous_tasks.py +1 -3
- intentkit/skills/tavily/base.py +1 -3
- intentkit/skills/tavily/tavily_extract.py +1 -2
- intentkit/skills/tavily/tavily_search.py +1 -3
- intentkit/skills/token/base.py +5 -5
- intentkit/skills/token/erc20_transfers.py +19 -19
- 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/base.py +3 -4
- intentkit/skills/twitter/follow_user.py +1 -2
- intentkit/skills/twitter/get_mentions.py +3 -4
- intentkit/skills/twitter/get_timeline.py +1 -2
- intentkit/skills/twitter/get_user_by_username.py +1 -2
- intentkit/skills/twitter/get_user_tweets.py +2 -3
- intentkit/skills/twitter/like_tweet.py +1 -2
- intentkit/skills/twitter/post_tweet.py +3 -4
- intentkit/skills/twitter/reply_tweet.py +3 -4
- intentkit/skills/twitter/retweet.py +1 -2
- intentkit/skills/twitter/search_tweets.py +1 -2
- intentkit/skills/unrealspeech/base.py +1 -3
- intentkit/skills/unrealspeech/text_to_speech.py +8 -8
- intentkit/skills/venice_audio/__init__.py +8 -9
- intentkit/skills/venice_audio/base.py +3 -4
- intentkit/skills/venice_audio/input.py +41 -41
- intentkit/skills/venice_audio/venice_audio.py +6 -6
- intentkit/skills/venice_image/__init__.py +5 -5
- intentkit/skills/venice_image/api.py +138 -138
- intentkit/skills/venice_image/base.py +3 -3
- 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 +9 -9
- 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/utils.py +77 -78
- intentkit/skills/web_scraper/base.py +1 -3
- intentkit/skills/web_scraper/document_indexer.py +1 -2
- intentkit/skills/web_scraper/scrape_and_index.py +4 -5
- intentkit/skills/web_scraper/utils.py +25 -26
- intentkit/skills/web_scraper/website_indexer.py +10 -11
- intentkit/skills/weth/__init__.py +4 -6
- intentkit/skills/wow/__init__.py +4 -6
- intentkit/skills/x402/__init__.py +11 -3
- intentkit/skills/x402/ask_agent.py +12 -78
- intentkit/skills/x402/base.py +90 -0
- intentkit/skills/x402/http_request.py +117 -0
- intentkit/skills/x402/schema.json +15 -10
- intentkit/skills/xmtp/base.py +3 -3
- intentkit/skills/xmtp/price.py +2 -2
- intentkit/skills/xmtp/swap.py +2 -4
- intentkit/skills/xmtp/transfer.py +4 -6
- intentkit/utils/error.py +2 -2
- intentkit/utils/logging.py +2 -4
- intentkit/utils/s3.py +8 -9
- intentkit/utils/schema.py +5 -5
- intentkit/utils/slack_alert.py +7 -8
- {intentkit-0.8.16.dev1.dist-info → intentkit-0.8.17.dev2.dist-info}/METADATA +3 -4
- intentkit-0.8.17.dev2.dist-info/RECORD +464 -0
- intentkit/models/generator.py +0 -347
- intentkit-0.8.16.dev1.dist-info/RECORD +0 -464
- {intentkit-0.8.16.dev1.dist-info → intentkit-0.8.17.dev2.dist-info}/WHEEL +0 -0
- {intentkit-0.8.16.dev1.dist-info → intentkit-0.8.17.dev2.dist-info}/licenses/LICENSE +0 -0
intentkit/skills/http/put.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
import httpx
|
|
5
5
|
from langchain_core.tools import ToolException
|
|
@@ -14,19 +14,19 @@ class HttpPutInput(BaseModel):
|
|
|
14
14
|
"""Input for HTTP PUT request."""
|
|
15
15
|
|
|
16
16
|
url: str = Field(description="The URL to send the PUT request to")
|
|
17
|
-
data:
|
|
17
|
+
data: dict[str, Any] | str | None = Field(
|
|
18
18
|
description="The data to send in the request body. Can be a dictionary (will be sent as JSON) or a string",
|
|
19
19
|
default=None,
|
|
20
20
|
)
|
|
21
|
-
headers:
|
|
21
|
+
headers: dict[str, str] | None = Field(
|
|
22
22
|
description="Optional headers to include in the request",
|
|
23
23
|
default=None,
|
|
24
24
|
)
|
|
25
|
-
params:
|
|
25
|
+
params: dict[str, Any] | None = Field(
|
|
26
26
|
description="Optional query parameters to include in the request",
|
|
27
27
|
default=None,
|
|
28
28
|
)
|
|
29
|
-
timeout:
|
|
29
|
+
timeout: float | None = Field(
|
|
30
30
|
description="Request timeout in seconds (default: 30)",
|
|
31
31
|
default=30.0,
|
|
32
32
|
)
|
|
@@ -52,14 +52,14 @@ class HttpPut(HttpBaseTool):
|
|
|
52
52
|
"Returns the response content as text. "
|
|
53
53
|
"Use this when you need to update or replace data on web APIs."
|
|
54
54
|
)
|
|
55
|
-
args_schema:
|
|
55
|
+
args_schema: type[BaseModel] = HttpPutInput
|
|
56
56
|
|
|
57
57
|
async def _arun(
|
|
58
58
|
self,
|
|
59
59
|
url: str,
|
|
60
|
-
data:
|
|
61
|
-
headers:
|
|
62
|
-
params:
|
|
60
|
+
data: dict[str, Any] | str | None = None,
|
|
61
|
+
headers: dict[str, str] | None = None,
|
|
62
|
+
params: dict[str, Any] | None = None,
|
|
63
63
|
timeout: float = 30.0,
|
|
64
64
|
**kwargs,
|
|
65
65
|
) -> str:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any,
|
|
2
|
+
from typing import Any, TypedDict
|
|
3
3
|
|
|
4
4
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
5
5
|
from intentkit.skills.lifi.base import LiFiBaseTool
|
|
@@ -22,9 +22,9 @@ class Config(SkillConfig):
|
|
|
22
22
|
"""Configuration for LiFi skills."""
|
|
23
23
|
|
|
24
24
|
states: SkillStates
|
|
25
|
-
default_slippage:
|
|
26
|
-
allowed_chains:
|
|
27
|
-
max_execution_time:
|
|
25
|
+
default_slippage: float | None = 0.03
|
|
26
|
+
allowed_chains: list[str] | None = None
|
|
27
|
+
max_execution_time: int | None = 300
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
async def get_skills(
|
intentkit/skills/lifi/base.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Type
|
|
2
|
-
|
|
3
1
|
from pydantic import BaseModel, Field
|
|
4
2
|
|
|
5
3
|
from intentkit.skills.base import IntentKitSkill
|
|
@@ -10,7 +8,7 @@ class LiFiBaseTool(IntentKitSkill):
|
|
|
10
8
|
|
|
11
9
|
name: str = Field(description="The name of the tool")
|
|
12
10
|
description: str = Field(description="A description of what the tool does")
|
|
13
|
-
args_schema:
|
|
11
|
+
args_schema: type[BaseModel]
|
|
14
12
|
|
|
15
13
|
@property
|
|
16
14
|
def category(self) -> str:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
import httpx
|
|
5
5
|
from coinbase_agentkit import CdpEvmWalletProvider
|
|
@@ -63,19 +63,19 @@ class TokenExecute(LiFiBaseTool):
|
|
|
63
63
|
"Use token_quote first to check rates and fees before executing.\n"
|
|
64
64
|
"Supports all major chains like Ethereum, Polygon, Arbitrum, Optimism, Base, and more."
|
|
65
65
|
)
|
|
66
|
-
args_schema:
|
|
66
|
+
args_schema: type[BaseModel] = TokenExecuteInput
|
|
67
67
|
api_url: str = LIFI_API_URL
|
|
68
68
|
|
|
69
69
|
# Configuration options
|
|
70
70
|
default_slippage: float = 0.03
|
|
71
|
-
allowed_chains:
|
|
71
|
+
allowed_chains: list[str] | None = None
|
|
72
72
|
max_execution_time: int = 300
|
|
73
|
-
quote_tool:
|
|
73
|
+
quote_tool: TokenQuote | None = Field(default=None, exclude=True)
|
|
74
74
|
|
|
75
75
|
def __init__(
|
|
76
76
|
self,
|
|
77
77
|
default_slippage: float = 0.03,
|
|
78
|
-
allowed_chains:
|
|
78
|
+
allowed_chains: list[str] | None = None,
|
|
79
79
|
max_execution_time: int = 300,
|
|
80
80
|
) -> None:
|
|
81
81
|
"""Initialize the TokenExecute skill with configuration options."""
|
|
@@ -90,7 +90,7 @@ class TokenExecute(LiFiBaseTool):
|
|
|
90
90
|
allowed_chains=allowed_chains,
|
|
91
91
|
)
|
|
92
92
|
|
|
93
|
-
def _format_quote_result(self, data:
|
|
93
|
+
def _format_quote_result(self, data: dict[str, Any]) -> str:
|
|
94
94
|
"""Format the quote result in a readable format."""
|
|
95
95
|
if self.quote_tool is None:
|
|
96
96
|
raise RuntimeError("Quote tool is not initialized")
|
|
@@ -104,7 +104,7 @@ class TokenExecute(LiFiBaseTool):
|
|
|
104
104
|
from_token: str,
|
|
105
105
|
to_token: str,
|
|
106
106
|
from_amount: str,
|
|
107
|
-
slippage:
|
|
107
|
+
slippage: float | None = None,
|
|
108
108
|
**kwargs,
|
|
109
109
|
) -> str:
|
|
110
110
|
"""Execute a token transfer."""
|
|
@@ -208,7 +208,7 @@ class TokenExecute(LiFiBaseTool):
|
|
|
208
208
|
from_amount: str,
|
|
209
209
|
slippage: float,
|
|
210
210
|
from_address: str,
|
|
211
|
-
) ->
|
|
211
|
+
) -> dict[str, Any] | str:
|
|
212
212
|
"""Get quote from LiFi API."""
|
|
213
213
|
api_params = build_quote_params(
|
|
214
214
|
from_chain,
|
|
@@ -250,8 +250,8 @@ class TokenExecute(LiFiBaseTool):
|
|
|
250
250
|
return data
|
|
251
251
|
|
|
252
252
|
async def _handle_token_approval(
|
|
253
|
-
self, wallet_provider: CdpEvmWalletProvider, quote_data:
|
|
254
|
-
) ->
|
|
253
|
+
self, wallet_provider: CdpEvmWalletProvider, quote_data: dict[str, Any]
|
|
254
|
+
) -> str | None:
|
|
255
255
|
"""Handle ERC20 token approval if needed."""
|
|
256
256
|
estimate = quote_data.get("estimate", {})
|
|
257
257
|
approval_address = estimate.get("approvalAddress")
|
|
@@ -276,7 +276,7 @@ class TokenExecute(LiFiBaseTool):
|
|
|
276
276
|
async def _execute_transfer_transaction(
|
|
277
277
|
self,
|
|
278
278
|
wallet_provider: CdpEvmWalletProvider,
|
|
279
|
-
quote_data:
|
|
279
|
+
quote_data: dict[str, Any],
|
|
280
280
|
from_address: str,
|
|
281
281
|
) -> str:
|
|
282
282
|
"""Execute the main transfer transaction."""
|
|
@@ -310,7 +310,7 @@ class TokenExecute(LiFiBaseTool):
|
|
|
310
310
|
tx_hash: str,
|
|
311
311
|
from_chain: str,
|
|
312
312
|
to_chain: str,
|
|
313
|
-
quote_data:
|
|
313
|
+
quote_data: dict[str, Any],
|
|
314
314
|
) -> str:
|
|
315
315
|
"""Finalize transfer and return formatted result."""
|
|
316
316
|
self.logger.info(f"Transaction sent: {tx_hash}")
|
|
@@ -417,7 +417,7 @@ class TokenExecute(LiFiBaseTool):
|
|
|
417
417
|
token_address: str,
|
|
418
418
|
approval_address: str,
|
|
419
419
|
amount: str,
|
|
420
|
-
) ->
|
|
420
|
+
) -> str | None:
|
|
421
421
|
"""Check if token allowance is sufficient and set approval if needed."""
|
|
422
422
|
try:
|
|
423
423
|
# Normalize addresses
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
import httpx
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
@@ -52,17 +52,17 @@ class TokenQuote(LiFiBaseTool):
|
|
|
52
52
|
"Use this tool to check rates, fees, and estimated time for token transfers without executing them.\n"
|
|
53
53
|
"Supports all major chains like Ethereum, Polygon, Arbitrum, Optimism, Base, and more."
|
|
54
54
|
)
|
|
55
|
-
args_schema:
|
|
55
|
+
args_schema: type[BaseModel] = TokenQuoteInput
|
|
56
56
|
api_url: str = LIFI_API_URL
|
|
57
57
|
|
|
58
58
|
# Configuration options
|
|
59
59
|
default_slippage: float = 0.03
|
|
60
|
-
allowed_chains:
|
|
60
|
+
allowed_chains: list[str] | None = None
|
|
61
61
|
|
|
62
62
|
def __init__(
|
|
63
63
|
self,
|
|
64
64
|
default_slippage: float = 0.03,
|
|
65
|
-
allowed_chains:
|
|
65
|
+
allowed_chains: list[str] | None = None,
|
|
66
66
|
) -> None:
|
|
67
67
|
"""Initialize the TokenQuote skill with configuration options."""
|
|
68
68
|
super().__init__()
|
|
@@ -76,7 +76,7 @@ class TokenQuote(LiFiBaseTool):
|
|
|
76
76
|
from_token: str,
|
|
77
77
|
to_token: str,
|
|
78
78
|
from_amount: str,
|
|
79
|
-
slippage:
|
|
79
|
+
slippage: float | None = None,
|
|
80
80
|
**kwargs,
|
|
81
81
|
) -> str:
|
|
82
82
|
"""Get a quote for token transfer."""
|
|
@@ -138,7 +138,7 @@ class TokenQuote(LiFiBaseTool):
|
|
|
138
138
|
self.logger.error("LiFi_Error: %s", str(e))
|
|
139
139
|
return f"An unexpected error occurred: {str(e)}"
|
|
140
140
|
|
|
141
|
-
def _format_quote_result(self, data:
|
|
141
|
+
def _format_quote_result(self, data: dict[str, Any]) -> str:
|
|
142
142
|
"""Format quote result into human-readable text."""
|
|
143
143
|
try:
|
|
144
144
|
# Get basic info
|
intentkit/skills/lifi/utils.py
CHANGED
|
@@ -5,7 +5,7 @@ Common utilities and helper functions for LiFi token transfer skills.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from decimal import ROUND_DOWN, Decimal, InvalidOperation
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
10
|
import httpx
|
|
11
11
|
from web3 import Web3
|
|
@@ -72,8 +72,8 @@ def validate_inputs(
|
|
|
72
72
|
to_token: str,
|
|
73
73
|
from_amount: str,
|
|
74
74
|
slippage: float,
|
|
75
|
-
allowed_chains:
|
|
76
|
-
) ->
|
|
75
|
+
allowed_chains: list[str] | None = None,
|
|
76
|
+
) -> str | None:
|
|
77
77
|
"""
|
|
78
78
|
Validate all input parameters for LiFi operations.
|
|
79
79
|
|
|
@@ -180,7 +180,7 @@ def handle_api_response(
|
|
|
180
180
|
from_chain: str,
|
|
181
181
|
to_token: str,
|
|
182
182
|
to_chain: str,
|
|
183
|
-
) ->
|
|
183
|
+
) -> tuple[dict[str, Any] | None, str | None]:
|
|
184
184
|
"""
|
|
185
185
|
Handle LiFi API response and return data or error message.
|
|
186
186
|
|
|
@@ -341,8 +341,8 @@ def build_quote_params(
|
|
|
341
341
|
to_token: str,
|
|
342
342
|
from_amount: str,
|
|
343
343
|
slippage: float,
|
|
344
|
-
from_address:
|
|
345
|
-
) ->
|
|
344
|
+
from_address: str | None = None,
|
|
345
|
+
) -> dict[str, Any]:
|
|
346
346
|
"""
|
|
347
347
|
Build parameters for LiFi quote API request.
|
|
348
348
|
|
|
@@ -385,7 +385,7 @@ def is_native_token(token_address: str) -> bool:
|
|
|
385
385
|
)
|
|
386
386
|
|
|
387
387
|
|
|
388
|
-
def _convert_hex_or_decimal(value: Any) ->
|
|
388
|
+
def _convert_hex_or_decimal(value: Any) -> int | None:
|
|
389
389
|
"""Convert LiFi transaction numeric values into integers."""
|
|
390
390
|
|
|
391
391
|
if value is None:
|
|
@@ -409,9 +409,9 @@ def _convert_hex_or_decimal(value: Any) -> Optional[int]:
|
|
|
409
409
|
|
|
410
410
|
|
|
411
411
|
def prepare_transaction_params(
|
|
412
|
-
transaction_request:
|
|
413
|
-
wallet_address:
|
|
414
|
-
) ->
|
|
412
|
+
transaction_request: dict[str, Any],
|
|
413
|
+
wallet_address: str | None = None,
|
|
414
|
+
) -> dict[str, Any]:
|
|
415
415
|
"""Prepare transaction parameters for the CDP wallet provider."""
|
|
416
416
|
|
|
417
417
|
to_address = transaction_request.get("to")
|
|
@@ -421,7 +421,7 @@ def prepare_transaction_params(
|
|
|
421
421
|
if not to_address:
|
|
422
422
|
raise Exception("Transaction request is missing destination address")
|
|
423
423
|
|
|
424
|
-
tx_params:
|
|
424
|
+
tx_params: dict[str, Any] = {
|
|
425
425
|
"to": Web3.to_checksum_address(to_address),
|
|
426
426
|
"data": data,
|
|
427
427
|
}
|
|
@@ -465,7 +465,7 @@ def prepare_transaction_params(
|
|
|
465
465
|
return tx_params
|
|
466
466
|
|
|
467
467
|
|
|
468
|
-
def format_quote_basic_info(data:
|
|
468
|
+
def format_quote_basic_info(data: dict[str, Any]) -> dict[str, Any]:
|
|
469
469
|
"""
|
|
470
470
|
Extract and format basic quote information.
|
|
471
471
|
|
|
@@ -503,7 +503,7 @@ def format_quote_basic_info(data: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
503
503
|
}
|
|
504
504
|
|
|
505
505
|
|
|
506
|
-
def format_fees_and_gas(data:
|
|
506
|
+
def format_fees_and_gas(data: dict[str, Any]) -> tuple[str, str]:
|
|
507
507
|
"""
|
|
508
508
|
Format fee and gas cost information from quote data.
|
|
509
509
|
|
|
@@ -517,7 +517,7 @@ def format_fees_and_gas(data: Dict[str, Any]) -> Tuple[str, str]:
|
|
|
517
517
|
|
|
518
518
|
# Extract gas and fee costs
|
|
519
519
|
gas_costs = estimate.get("gasCosts", [])
|
|
520
|
-
fee_costs:
|
|
520
|
+
fee_costs: list[dict[str, Any]] = []
|
|
521
521
|
|
|
522
522
|
# Collect fee information from included steps
|
|
523
523
|
for step in data.get("includedSteps", []):
|
|
@@ -584,7 +584,7 @@ def format_fees_and_gas(data: Dict[str, Any]) -> Tuple[str, str]:
|
|
|
584
584
|
return fees_text, gas_text
|
|
585
585
|
|
|
586
586
|
|
|
587
|
-
def format_route_info(data:
|
|
587
|
+
def format_route_info(data: dict[str, Any]) -> str:
|
|
588
588
|
"""
|
|
589
589
|
Format routing information from quote data.
|
|
590
590
|
|
|
@@ -681,7 +681,7 @@ def get_explorer_url(chain_id: int, tx_hash: str) -> str:
|
|
|
681
681
|
|
|
682
682
|
|
|
683
683
|
def format_transaction_result(
|
|
684
|
-
tx_hash: str, chain_id: int, token_info:
|
|
684
|
+
tx_hash: str, chain_id: int, token_info: dict[str, str] | None = None
|
|
685
685
|
) -> str:
|
|
686
686
|
"""
|
|
687
687
|
Format transaction result with explorer link.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Wallet Portfolio Skills for IntentKit."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import NotRequired, TypedDict
|
|
5
5
|
|
|
6
6
|
from intentkit.config.config import config as system_config
|
|
7
7
|
from intentkit.skills.base import SkillConfig, SkillState
|
|
@@ -28,14 +28,14 @@ class Config(SkillConfig):
|
|
|
28
28
|
|
|
29
29
|
api_key: str
|
|
30
30
|
states: SkillStates
|
|
31
|
-
supported_chains: NotRequired[
|
|
31
|
+
supported_chains: NotRequired[dict[str, bool]] = {"evm": True, "solana": True}
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
async def get_skills(
|
|
35
35
|
config: "Config",
|
|
36
36
|
is_private: bool,
|
|
37
37
|
**_,
|
|
38
|
-
) ->
|
|
38
|
+
) -> list[WalletBaseTool]:
|
|
39
39
|
"""Get all Wallet Portfolio skills.
|
|
40
40
|
|
|
41
41
|
Args:
|
intentkit/skills/moralis/api.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""API interface for wallet data providers (EVM chains and Solana)."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import Dict
|
|
5
4
|
|
|
6
5
|
import httpx
|
|
7
6
|
|
|
@@ -163,7 +162,7 @@ async def fetch_net_worth(api_key: str, address: str) -> dict:
|
|
|
163
162
|
#############################################
|
|
164
163
|
|
|
165
164
|
|
|
166
|
-
async def fetch_solana_api(api_key: str, endpoint: str, params:
|
|
165
|
+
async def fetch_solana_api(api_key: str, endpoint: str, params: dict = None) -> dict:
|
|
167
166
|
"""Base function for Solana API calls using Moralis.
|
|
168
167
|
|
|
169
168
|
Args:
|
|
@@ -200,7 +199,7 @@ async def fetch_solana_api(api_key: str, endpoint: str, params: Dict = None) ->
|
|
|
200
199
|
|
|
201
200
|
async def get_solana_portfolio(
|
|
202
201
|
api_key: str, address: str, network: str = "mainnet"
|
|
203
|
-
) ->
|
|
202
|
+
) -> dict:
|
|
204
203
|
"""Get complete portfolio for a Solana wallet.
|
|
205
204
|
|
|
206
205
|
Args:
|
|
@@ -217,7 +216,7 @@ async def get_solana_portfolio(
|
|
|
217
216
|
|
|
218
217
|
async def get_solana_balance(
|
|
219
218
|
api_key: str, address: str, network: str = "mainnet"
|
|
220
|
-
) ->
|
|
219
|
+
) -> dict:
|
|
221
220
|
"""Get native SOL balance.
|
|
222
221
|
|
|
223
222
|
Args:
|
|
@@ -234,7 +233,7 @@ async def get_solana_balance(
|
|
|
234
233
|
|
|
235
234
|
async def get_solana_spl_tokens(
|
|
236
235
|
api_key: str, address: str, network: str = "mainnet"
|
|
237
|
-
) ->
|
|
236
|
+
) -> dict:
|
|
238
237
|
"""Get SPL token balances.
|
|
239
238
|
|
|
240
239
|
Args:
|
|
@@ -249,7 +248,7 @@ async def get_solana_spl_tokens(
|
|
|
249
248
|
return await fetch_solana_api(api_key, endpoint)
|
|
250
249
|
|
|
251
250
|
|
|
252
|
-
async def get_solana_nfts(api_key: str, address: str, network: str = "mainnet") ->
|
|
251
|
+
async def get_solana_nfts(api_key: str, address: str, network: str = "mainnet") -> dict:
|
|
253
252
|
"""Get NFTs owned by a Solana wallet.
|
|
254
253
|
|
|
255
254
|
Args:
|
|
@@ -266,7 +265,7 @@ async def get_solana_nfts(api_key: str, address: str, network: str = "mainnet")
|
|
|
266
265
|
|
|
267
266
|
async def get_token_price(
|
|
268
267
|
api_key: str, token_address: str, network: str = "mainnet"
|
|
269
|
-
) ->
|
|
268
|
+
) -> dict:
|
|
270
269
|
"""Get token price by mint address.
|
|
271
270
|
|
|
272
271
|
Args:
|
intentkit/skills/moralis/base.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Base class for Wallet Portfolio tools."""
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional, Type
|
|
4
|
-
|
|
5
3
|
from langchain_core.tools.base import ToolException
|
|
6
4
|
from pydantic import BaseModel, Field
|
|
7
5
|
|
|
@@ -29,10 +27,10 @@ class WalletBaseTool(IntentKitSkill):
|
|
|
29
27
|
|
|
30
28
|
name: str = Field(description="The name of the tool")
|
|
31
29
|
description: str = Field(description="A description of what the tool does")
|
|
32
|
-
args_schema:
|
|
30
|
+
args_schema: type[BaseModel]
|
|
33
31
|
|
|
34
32
|
# Optional fields for blockchain providers
|
|
35
|
-
solana_networks:
|
|
33
|
+
solana_networks: list[str] | None = Field(
|
|
36
34
|
default=SOLANA_NETWORKS, description="Supported Solana networks"
|
|
37
35
|
)
|
|
38
36
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""fetching wallet portfolio for a specific blockchain."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import List, Optional, Type
|
|
5
4
|
|
|
6
5
|
from pydantic import BaseModel, Field
|
|
7
6
|
|
|
@@ -27,7 +26,7 @@ class ChainTokenBalance(BaseModel):
|
|
|
27
26
|
contract_address: str = Field(..., description="Token contract address")
|
|
28
27
|
symbol: str = Field(..., description="Token symbol")
|
|
29
28
|
name: str = Field(..., description="Token name")
|
|
30
|
-
logo:
|
|
29
|
+
logo: str | None = Field(None, description="Token logo URL")
|
|
31
30
|
decimals: int = Field(..., description="Token decimals")
|
|
32
31
|
balance: float = Field(..., description="Token balance")
|
|
33
32
|
balance_raw: str = Field(..., description="Raw token balance")
|
|
@@ -38,12 +37,12 @@ class TokenApproval(BaseModel):
|
|
|
38
37
|
"""Model for token approval."""
|
|
39
38
|
|
|
40
39
|
token_address: str = Field(..., description="Token contract address")
|
|
41
|
-
token_symbol:
|
|
42
|
-
token_name:
|
|
40
|
+
token_symbol: str | None = Field(None, description="Token symbol")
|
|
41
|
+
token_name: str | None = Field(None, description="Token name")
|
|
43
42
|
spender: str = Field(..., description="Spender address (contract)")
|
|
44
|
-
spender_name:
|
|
43
|
+
spender_name: str | None = Field(None, description="Spender name if known")
|
|
45
44
|
allowance: str = Field(..., description="Raw approval amount")
|
|
46
|
-
allowance_formatted:
|
|
45
|
+
allowance_formatted: float | None = Field(
|
|
47
46
|
None, description="Formatted approval amount"
|
|
48
47
|
)
|
|
49
48
|
unlimited: bool = Field(False, description="Whether the approval is unlimited")
|
|
@@ -55,17 +54,17 @@ class ChainPortfolioOutput(BaseModel):
|
|
|
55
54
|
address: str = Field(..., description="Wallet address")
|
|
56
55
|
chain_id: int = Field(..., description="Chain ID")
|
|
57
56
|
chain_name: str = Field(..., description="Chain name")
|
|
58
|
-
native_token:
|
|
57
|
+
native_token: ChainTokenBalance | None = Field(
|
|
59
58
|
None, description="Native token balance"
|
|
60
59
|
)
|
|
61
|
-
tokens:
|
|
60
|
+
tokens: list[ChainTokenBalance] = Field(
|
|
62
61
|
default_factory=list, description="List of token balances"
|
|
63
62
|
)
|
|
64
63
|
total_usd_value: float = Field(0.0, description="Total USD value on this chain")
|
|
65
|
-
approvals:
|
|
64
|
+
approvals: list[TokenApproval] | None = Field(
|
|
66
65
|
None, description="Token approvals if requested"
|
|
67
66
|
)
|
|
68
|
-
error:
|
|
67
|
+
error: str | None = Field(None, description="Error message if any")
|
|
69
68
|
|
|
70
69
|
|
|
71
70
|
class FetchChainPortfolio(WalletBaseTool):
|
|
@@ -87,7 +86,7 @@ class FetchChainPortfolio(WalletBaseTool):
|
|
|
87
86
|
"- Token approvals (optional)\n"
|
|
88
87
|
"Use this tool whenever a user wants to see their holdings on a specific blockchain."
|
|
89
88
|
)
|
|
90
|
-
args_schema:
|
|
89
|
+
args_schema: type[BaseModel] = FetchChainPortfolioInput
|
|
91
90
|
|
|
92
91
|
async def _arun(
|
|
93
92
|
self, address: str, chain_id: int, include_approvals: bool = False, **kwargs
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel, Field
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ class FetchNftPortfolioInput(BaseModel):
|
|
|
16
16
|
"""Input for FetchNftPortfolio tool."""
|
|
17
17
|
|
|
18
18
|
address: str = Field(..., description="Wallet address")
|
|
19
|
-
chain_id:
|
|
19
|
+
chain_id: int | None = Field(
|
|
20
20
|
None,
|
|
21
21
|
description="Chain ID (if not specified, fetches from all supported chains)",
|
|
22
22
|
)
|
|
@@ -26,7 +26,7 @@ class FetchNftPortfolioInput(BaseModel):
|
|
|
26
26
|
solana_network: str = Field(
|
|
27
27
|
default="mainnet", description="Solana network to use (mainnet or devnet)"
|
|
28
28
|
)
|
|
29
|
-
limit:
|
|
29
|
+
limit: int | None = Field(100, description="Maximum number of NFTs to return")
|
|
30
30
|
normalize_metadata: bool = Field(
|
|
31
31
|
True, description="Whether to normalize metadata across different standards"
|
|
32
32
|
)
|
|
@@ -35,12 +35,12 @@ class FetchNftPortfolioInput(BaseModel):
|
|
|
35
35
|
class NftMetadata(BaseModel):
|
|
36
36
|
"""Model for NFT metadata."""
|
|
37
37
|
|
|
38
|
-
name:
|
|
39
|
-
description:
|
|
40
|
-
image:
|
|
41
|
-
animation_url:
|
|
42
|
-
attributes:
|
|
43
|
-
external_url:
|
|
38
|
+
name: str | None = Field(None, description="NFT name")
|
|
39
|
+
description: str | None = Field(None, description="NFT description")
|
|
40
|
+
image: str | None = Field(None, description="NFT image URL")
|
|
41
|
+
animation_url: str | None = Field(None, description="NFT animation URL")
|
|
42
|
+
attributes: list[dict] | None = Field(None, description="NFT attributes/traits")
|
|
43
|
+
external_url: str | None = Field(None, description="External URL")
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class NftItem(BaseModel):
|
|
@@ -48,14 +48,14 @@ class NftItem(BaseModel):
|
|
|
48
48
|
|
|
49
49
|
token_id: str = Field(..., description="NFT token ID")
|
|
50
50
|
token_address: str = Field(..., description="NFT contract address")
|
|
51
|
-
contract_type:
|
|
51
|
+
contract_type: str | None = Field(
|
|
52
52
|
None, description="NFT contract type (ERC721, ERC1155, etc.)"
|
|
53
53
|
)
|
|
54
|
-
name:
|
|
55
|
-
symbol:
|
|
54
|
+
name: str | None = Field(None, description="NFT name")
|
|
55
|
+
symbol: str | None = Field(None, description="NFT symbol")
|
|
56
56
|
owner_of: str = Field(..., description="Owner address")
|
|
57
|
-
metadata:
|
|
58
|
-
floor_price:
|
|
57
|
+
metadata: NftMetadata | None = Field(None, description="NFT metadata")
|
|
58
|
+
floor_price: float | None = Field(None, description="Floor price if available")
|
|
59
59
|
chain: str = Field("eth", description="Blockchain network")
|
|
60
60
|
|
|
61
61
|
|
|
@@ -63,13 +63,13 @@ class NftPortfolioOutput(BaseModel):
|
|
|
63
63
|
"""Output for FetchNftPortfolio tool."""
|
|
64
64
|
|
|
65
65
|
address: str = Field(..., description="Wallet address")
|
|
66
|
-
nfts:
|
|
66
|
+
nfts: list[NftItem] = Field(default_factory=list, description="List of NFT items")
|
|
67
67
|
total_count: int = Field(0, description="Total count of NFTs")
|
|
68
|
-
chains:
|
|
68
|
+
chains: list[str] = Field(
|
|
69
69
|
default_factory=list, description="Chains included in the response"
|
|
70
70
|
)
|
|
71
|
-
cursor:
|
|
72
|
-
error:
|
|
71
|
+
cursor: str | None = Field(None, description="Cursor for pagination")
|
|
72
|
+
error: str | None = Field(None, description="Error message if any")
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
class FetchNftPortfolio(WalletBaseTool):
|
|
@@ -90,12 +90,12 @@ class FetchNftPortfolio(WalletBaseTool):
|
|
|
90
90
|
"- Floor prices if available\n"
|
|
91
91
|
"Use this tool whenever a user asks about their NFTs or digital collectibles."
|
|
92
92
|
)
|
|
93
|
-
args_schema:
|
|
93
|
+
args_schema: type[BaseModel] = FetchNftPortfolioInput
|
|
94
94
|
|
|
95
95
|
async def _arun(
|
|
96
96
|
self,
|
|
97
97
|
address: str,
|
|
98
|
-
chain_id:
|
|
98
|
+
chain_id: int | None = None,
|
|
99
99
|
include_solana: bool = False,
|
|
100
100
|
solana_network: str = "mainnet",
|
|
101
101
|
limit: int = 100,
|
|
@@ -156,7 +156,7 @@ class FetchNftPortfolio(WalletBaseTool):
|
|
|
156
156
|
chain_id: int,
|
|
157
157
|
limit: int,
|
|
158
158
|
normalize_metadata: bool,
|
|
159
|
-
result:
|
|
159
|
+
result: dict[str, Any],
|
|
160
160
|
) -> None:
|
|
161
161
|
"""Fetch NFTs from an EVM chain.
|
|
162
162
|
|
|
@@ -222,7 +222,7 @@ class FetchNftPortfolio(WalletBaseTool):
|
|
|
222
222
|
result["nfts"].append(nft_item)
|
|
223
223
|
|
|
224
224
|
async def _fetch_solana_nfts(
|
|
225
|
-
self, address: str, network: str, limit: int, result:
|
|
225
|
+
self, address: str, network: str, limit: int, result: dict[str, Any]
|
|
226
226
|
) -> None:
|
|
227
227
|
"""Fetch NFTs from Solana.
|
|
228
228
|
|