intentkit 0.8.6.dev2__py3-none-any.whl → 0.8.17__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.

Files changed (312) hide show
  1. intentkit/__init__.py +1 -1
  2. intentkit/abstracts/agent.py +4 -5
  3. intentkit/abstracts/engine.py +5 -5
  4. intentkit/abstracts/graph.py +10 -5
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +3 -2
  8. intentkit/clients/cdp.py +53 -92
  9. intentkit/clients/twitter.py +56 -57
  10. intentkit/clients/web3.py +1 -3
  11. intentkit/config/config.py +5 -0
  12. intentkit/core/agent.py +16 -388
  13. intentkit/core/asset.py +64 -18
  14. intentkit/core/client.py +1 -1
  15. intentkit/core/credit.py +19 -20
  16. intentkit/core/engine.py +26 -11
  17. intentkit/core/node.py +2 -1
  18. intentkit/core/prompt.py +53 -15
  19. intentkit/core/scheduler.py +9 -9
  20. intentkit/core/statistics.py +6 -7
  21. intentkit/models/agent.py +256 -176
  22. intentkit/models/agent_data.py +62 -36
  23. intentkit/models/agent_schema.json +6 -9
  24. intentkit/models/app_setting.py +6 -6
  25. intentkit/models/chat.py +28 -24
  26. intentkit/models/conversation.py +8 -8
  27. intentkit/models/credit.py +62 -64
  28. intentkit/models/db.py +8 -7
  29. intentkit/models/db_mig.py +2 -2
  30. intentkit/models/llm.csv +15 -12
  31. intentkit/models/llm.py +18 -16
  32. intentkit/models/redis.py +2 -3
  33. intentkit/models/skill.py +62 -66
  34. intentkit/models/skills.csv +30 -26
  35. intentkit/models/user.py +46 -21
  36. intentkit/skills/acolyt/__init__.py +2 -9
  37. intentkit/skills/acolyt/ask.py +3 -4
  38. intentkit/skills/acolyt/base.py +4 -9
  39. intentkit/skills/aixbt/__init__.py +2 -13
  40. intentkit/skills/aixbt/base.py +1 -7
  41. intentkit/skills/aixbt/projects.py +14 -15
  42. intentkit/skills/allora/__init__.py +2 -9
  43. intentkit/skills/allora/base.py +4 -9
  44. intentkit/skills/allora/price.py +3 -4
  45. intentkit/skills/base.py +175 -52
  46. intentkit/skills/basename/__init__.py +4 -8
  47. intentkit/skills/carv/__init__.py +115 -121
  48. intentkit/skills/carv/base.py +184 -185
  49. intentkit/skills/carv/fetch_news.py +3 -3
  50. intentkit/skills/carv/onchain_query.py +4 -4
  51. intentkit/skills/carv/token_info_and_price.py +5 -5
  52. intentkit/skills/casino/__init__.py +4 -15
  53. intentkit/skills/casino/base.py +1 -7
  54. intentkit/skills/casino/deck_draw.py +5 -8
  55. intentkit/skills/casino/deck_shuffle.py +6 -6
  56. intentkit/skills/casino/dice_roll.py +2 -4
  57. intentkit/skills/cdp/__init__.py +3 -10
  58. intentkit/skills/cdp/base.py +1 -7
  59. intentkit/skills/cdp/schema.json +1 -17
  60. intentkit/skills/chainlist/__init__.py +2 -7
  61. intentkit/skills/chainlist/base.py +1 -7
  62. intentkit/skills/chainlist/chain_lookup.py +18 -18
  63. intentkit/skills/common/__init__.py +2 -9
  64. intentkit/skills/common/base.py +1 -7
  65. intentkit/skills/common/current_time.py +1 -2
  66. intentkit/skills/cookiefun/__init__.py +6 -9
  67. intentkit/skills/cookiefun/base.py +2 -7
  68. intentkit/skills/cookiefun/get_account_details.py +7 -7
  69. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  70. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  71. intentkit/skills/cookiefun/get_sectors.py +3 -3
  72. intentkit/skills/cookiefun/search_accounts.py +9 -9
  73. intentkit/skills/cryptocompare/__init__.py +7 -24
  74. intentkit/skills/cryptocompare/api.py +2 -3
  75. intentkit/skills/cryptocompare/base.py +10 -24
  76. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  77. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  78. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  79. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  80. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  81. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  82. intentkit/skills/cryptopanic/__init__.py +7 -10
  83. intentkit/skills/cryptopanic/base.py +51 -55
  84. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  85. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  86. intentkit/skills/dapplooker/__init__.py +2 -9
  87. intentkit/skills/dapplooker/base.py +4 -9
  88. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  89. intentkit/skills/defillama/__init__.py +24 -74
  90. intentkit/skills/defillama/api.py +6 -9
  91. intentkit/skills/defillama/base.py +8 -19
  92. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  93. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  94. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  95. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  96. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  97. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  98. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  99. intentkit/skills/defillama/config/chains.py +1 -3
  100. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  101. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  102. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  103. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  104. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  105. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  106. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  107. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  108. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  109. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  110. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  111. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  112. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  113. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  114. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  115. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  116. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  117. intentkit/skills/dexscreener/__init__.py +97 -102
  118. intentkit/skills/dexscreener/base.py +125 -130
  119. intentkit/skills/dexscreener/get_pair_info.py +4 -5
  120. intentkit/skills/dexscreener/get_token_pairs.py +4 -5
  121. intentkit/skills/dexscreener/get_tokens_info.py +7 -8
  122. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  123. intentkit/skills/dexscreener/search_token.py +182 -184
  124. intentkit/skills/dexscreener/utils.py +15 -14
  125. intentkit/skills/dune_analytics/__init__.py +7 -9
  126. intentkit/skills/dune_analytics/base.py +48 -52
  127. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  128. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  129. intentkit/skills/elfa/__init__.py +5 -18
  130. intentkit/skills/elfa/base.py +10 -14
  131. intentkit/skills/elfa/mention.py +19 -21
  132. intentkit/skills/elfa/stats.py +4 -4
  133. intentkit/skills/elfa/tokens.py +12 -12
  134. intentkit/skills/elfa/utils.py +26 -28
  135. intentkit/skills/enso/__init__.py +11 -31
  136. intentkit/skills/enso/base.py +9 -15
  137. intentkit/skills/enso/best_yield.py +5 -7
  138. intentkit/skills/enso/networks.py +3 -9
  139. intentkit/skills/enso/prices.py +2 -4
  140. intentkit/skills/enso/route.py +6 -12
  141. intentkit/skills/enso/tokens.py +4 -16
  142. intentkit/skills/enso/wallet.py +6 -6
  143. intentkit/skills/erc20/__init__.py +5 -11
  144. intentkit/skills/erc721/__init__.py +5 -9
  145. intentkit/skills/firecrawl/__init__.py +5 -18
  146. intentkit/skills/firecrawl/base.py +4 -9
  147. intentkit/skills/firecrawl/clear.py +4 -8
  148. intentkit/skills/firecrawl/crawl.py +19 -19
  149. intentkit/skills/firecrawl/query.py +4 -3
  150. intentkit/skills/firecrawl/scrape.py +17 -22
  151. intentkit/skills/firecrawl/utils.py +50 -42
  152. intentkit/skills/github/__init__.py +2 -7
  153. intentkit/skills/github/base.py +1 -7
  154. intentkit/skills/github/github_search.py +1 -2
  155. intentkit/skills/heurist/__init__.py +8 -27
  156. intentkit/skills/heurist/base.py +4 -9
  157. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  158. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  159. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  160. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  161. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  162. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  163. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  164. intentkit/skills/http/__init__.py +4 -15
  165. intentkit/skills/http/base.py +1 -7
  166. intentkit/skills/http/get.py +21 -16
  167. intentkit/skills/http/post.py +23 -18
  168. intentkit/skills/http/put.py +23 -18
  169. intentkit/skills/lifi/__init__.py +5 -10
  170. intentkit/skills/lifi/base.py +1 -7
  171. intentkit/skills/lifi/token_execute.py +14 -17
  172. intentkit/skills/lifi/token_quote.py +7 -9
  173. intentkit/skills/lifi/utils.py +16 -16
  174. intentkit/skills/moralis/__init__.py +6 -10
  175. intentkit/skills/moralis/api.py +6 -7
  176. intentkit/skills/moralis/base.py +5 -10
  177. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  178. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  179. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  180. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  181. intentkit/skills/morpho/__init__.py +5 -9
  182. intentkit/skills/nation/__init__.py +4 -9
  183. intentkit/skills/nation/base.py +5 -10
  184. intentkit/skills/nation/nft_check.py +3 -4
  185. intentkit/skills/onchain.py +23 -0
  186. intentkit/skills/openai/__init__.py +17 -18
  187. intentkit/skills/openai/base.py +10 -14
  188. intentkit/skills/openai/dalle_image_generation.py +3 -8
  189. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  190. intentkit/skills/openai/gpt_image_generation.py +4 -8
  191. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  192. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  193. intentkit/skills/openai/image_to_text.py +3 -7
  194. intentkit/skills/openai/schema.json +32 -0
  195. intentkit/skills/portfolio/__init__.py +11 -35
  196. intentkit/skills/portfolio/base.py +33 -19
  197. intentkit/skills/portfolio/token_balances.py +21 -21
  198. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  199. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  200. intentkit/skills/portfolio/wallet_history.py +31 -31
  201. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  202. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  203. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  204. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  205. intentkit/skills/portfolio/wallet_stats.py +3 -3
  206. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  207. intentkit/skills/pyth/__init__.py +4 -10
  208. intentkit/skills/skills.toml +4 -0
  209. intentkit/skills/slack/__init__.py +5 -17
  210. intentkit/skills/slack/base.py +3 -9
  211. intentkit/skills/slack/get_channel.py +8 -8
  212. intentkit/skills/slack/get_message.py +9 -9
  213. intentkit/skills/slack/schedule_message.py +5 -5
  214. intentkit/skills/slack/send_message.py +3 -5
  215. intentkit/skills/supabase/__init__.py +7 -23
  216. intentkit/skills/supabase/base.py +1 -7
  217. intentkit/skills/supabase/delete_data.py +4 -4
  218. intentkit/skills/supabase/fetch_data.py +12 -12
  219. intentkit/skills/supabase/insert_data.py +4 -4
  220. intentkit/skills/supabase/invoke_function.py +6 -6
  221. intentkit/skills/supabase/update_data.py +6 -6
  222. intentkit/skills/supabase/upsert_data.py +4 -4
  223. intentkit/skills/superfluid/__init__.py +5 -9
  224. intentkit/skills/system/__init__.py +7 -24
  225. intentkit/skills/system/add_autonomous_task.py +10 -12
  226. intentkit/skills/system/delete_autonomous_task.py +2 -2
  227. intentkit/skills/system/edit_autonomous_task.py +14 -18
  228. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  229. intentkit/skills/system/read_agent_api_key.py +6 -4
  230. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  231. intentkit/skills/tavily/__init__.py +3 -12
  232. intentkit/skills/tavily/base.py +4 -9
  233. intentkit/skills/tavily/tavily_extract.py +2 -4
  234. intentkit/skills/tavily/tavily_search.py +4 -6
  235. intentkit/skills/token/__init__.py +5 -10
  236. intentkit/skills/token/base.py +7 -11
  237. intentkit/skills/token/erc20_transfers.py +19 -19
  238. intentkit/skills/token/token_analytics.py +3 -3
  239. intentkit/skills/token/token_price.py +13 -13
  240. intentkit/skills/token/token_search.py +9 -9
  241. intentkit/skills/twitter/__init__.py +11 -35
  242. intentkit/skills/twitter/base.py +22 -34
  243. intentkit/skills/twitter/follow_user.py +2 -6
  244. intentkit/skills/twitter/get_mentions.py +5 -12
  245. intentkit/skills/twitter/get_timeline.py +4 -12
  246. intentkit/skills/twitter/get_user_by_username.py +2 -6
  247. intentkit/skills/twitter/get_user_tweets.py +5 -13
  248. intentkit/skills/twitter/like_tweet.py +2 -6
  249. intentkit/skills/twitter/post_tweet.py +6 -9
  250. intentkit/skills/twitter/reply_tweet.py +6 -9
  251. intentkit/skills/twitter/retweet.py +2 -6
  252. intentkit/skills/twitter/search_tweets.py +4 -12
  253. intentkit/skills/unrealspeech/__init__.py +2 -7
  254. intentkit/skills/unrealspeech/base.py +2 -8
  255. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  256. intentkit/skills/venice_audio/__init__.py +98 -106
  257. intentkit/skills/venice_audio/base.py +117 -121
  258. intentkit/skills/venice_audio/input.py +41 -41
  259. intentkit/skills/venice_audio/venice_audio.py +7 -11
  260. intentkit/skills/venice_image/__init__.py +147 -154
  261. intentkit/skills/venice_image/api.py +138 -138
  262. intentkit/skills/venice_image/base.py +185 -192
  263. intentkit/skills/venice_image/config.py +33 -35
  264. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  265. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  266. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  267. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  268. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  269. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  270. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  271. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  272. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  273. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  274. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  275. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  276. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  277. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  278. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  279. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  280. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  281. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  282. intentkit/skills/venice_image/utils.py +77 -78
  283. intentkit/skills/web_scraper/__init__.py +5 -18
  284. intentkit/skills/web_scraper/base.py +21 -7
  285. intentkit/skills/web_scraper/document_indexer.py +7 -6
  286. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  287. intentkit/skills/web_scraper/utils.py +62 -63
  288. intentkit/skills/web_scraper/website_indexer.py +17 -19
  289. intentkit/skills/weth/__init__.py +5 -11
  290. intentkit/skills/wow/__init__.py +5 -11
  291. intentkit/skills/x402/__init__.py +61 -0
  292. intentkit/skills/x402/ask_agent.py +98 -0
  293. intentkit/skills/x402/base.py +99 -0
  294. intentkit/skills/x402/http_request.py +117 -0
  295. intentkit/skills/x402/schema.json +45 -0
  296. intentkit/skills/x402/x402.webp +0 -0
  297. intentkit/skills/xmtp/__init__.py +4 -15
  298. intentkit/skills/xmtp/base.py +5 -5
  299. intentkit/skills/xmtp/price.py +6 -6
  300. intentkit/skills/xmtp/swap.py +6 -8
  301. intentkit/skills/xmtp/transfer.py +4 -6
  302. intentkit/utils/error.py +2 -2
  303. intentkit/utils/logging.py +2 -4
  304. intentkit/utils/s3.py +8 -9
  305. intentkit/utils/schema.py +100 -0
  306. intentkit/utils/slack_alert.py +7 -8
  307. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +3 -4
  308. intentkit-0.8.17.dist-info/RECORD +466 -0
  309. intentkit/models/generator.py +0 -347
  310. intentkit-0.8.6.dev2.dist-info/RECORD +0 -457
  311. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  312. {intentkit-0.8.6.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,8 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type, Union
2
+ from typing import Any
3
3
 
4
4
  import httpx
5
+ from langchain_core.tools import ToolException
5
6
  from pydantic import BaseModel, Field
6
7
 
7
8
  from intentkit.skills.http.base import HttpBaseTool
@@ -13,19 +14,19 @@ class HttpPostInput(BaseModel):
13
14
  """Input for HTTP POST request."""
14
15
 
15
16
  url: str = Field(description="The URL to send the POST request to")
16
- data: Optional[Union[Dict[str, Any], str]] = Field(
17
+ data: dict[str, Any] | str | None = Field(
17
18
  description="The data to send in the request body. Can be a dictionary (will be sent as JSON) or a string",
18
19
  default=None,
19
20
  )
20
- headers: Optional[Dict[str, str]] = Field(
21
+ headers: dict[str, str] | None = Field(
21
22
  description="Optional headers to include in the request",
22
23
  default=None,
23
24
  )
24
- params: Optional[Dict[str, Any]] = Field(
25
+ params: dict[str, Any] | None = Field(
25
26
  description="Optional query parameters to include in the request",
26
27
  default=None,
27
28
  )
28
- timeout: Optional[float] = Field(
29
+ timeout: float | None = Field(
29
30
  description="Request timeout in seconds (default: 30)",
30
31
  default=30.0,
31
32
  )
@@ -51,14 +52,14 @@ class HttpPost(HttpBaseTool):
51
52
  "Returns the response content as text. "
52
53
  "Use this when you need to send data to web APIs or submit forms."
53
54
  )
54
- args_schema: Type[BaseModel] = HttpPostInput
55
+ args_schema: type[BaseModel] = HttpPostInput
55
56
 
56
57
  async def _arun(
57
58
  self,
58
59
  url: str,
59
- data: Optional[Union[Dict[str, Any], str]] = None,
60
- headers: Optional[Dict[str, str]] = None,
61
- params: Optional[Dict[str, Any]] = None,
60
+ data: dict[str, Any] | str | None = None,
61
+ headers: dict[str, str] | None = None,
62
+ params: dict[str, Any] | None = None,
62
63
  timeout: float = 30.0,
63
64
  **kwargs,
64
65
  ) -> str:
@@ -100,12 +101,16 @@ class HttpPost(HttpBaseTool):
100
101
  # Return response content
101
102
  return f"Status: {response.status_code}\nContent: {response.text}"
102
103
 
103
- except httpx.TimeoutException:
104
- return f"Error: Request to {url} timed out after {timeout} seconds"
105
- except httpx.HTTPStatusError as e:
106
- return f"Error: HTTP {e.response.status_code} - {e.response.text}"
107
- except httpx.RequestError as e:
108
- return f"Error: Failed to connect to {url} - {str(e)}"
109
- except Exception as e:
110
- logger.error(f"Unexpected error in HTTP POST request: {e}")
111
- return f"Error: Unexpected error occurred - {str(e)}"
104
+ except httpx.TimeoutException as exc:
105
+ raise ToolException(
106
+ f"Request to {url} timed out after {timeout} seconds"
107
+ ) from exc
108
+ except httpx.HTTPStatusError as exc:
109
+ raise ToolException(
110
+ f"HTTP {exc.response.status_code} - {exc.response.text}"
111
+ ) from exc
112
+ except httpx.RequestError as exc:
113
+ raise ToolException(f"Failed to connect to {url} - {str(exc)}") from exc
114
+ except Exception as exc: # noqa: BLE001
115
+ logger.error("Unexpected error in HTTP POST request", exc_info=exc)
116
+ raise ToolException(f"Unexpected error occurred - {str(exc)}") from exc
@@ -1,7 +1,8 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional, Type, Union
2
+ from typing import Any
3
3
 
4
4
  import httpx
5
+ from langchain_core.tools import ToolException
5
6
  from pydantic import BaseModel, Field
6
7
 
7
8
  from intentkit.skills.http.base import HttpBaseTool
@@ -13,19 +14,19 @@ class HttpPutInput(BaseModel):
13
14
  """Input for HTTP PUT request."""
14
15
 
15
16
  url: str = Field(description="The URL to send the PUT request to")
16
- data: Optional[Union[Dict[str, Any], str]] = Field(
17
+ data: dict[str, Any] | str | None = Field(
17
18
  description="The data to send in the request body. Can be a dictionary (will be sent as JSON) or a string",
18
19
  default=None,
19
20
  )
20
- headers: Optional[Dict[str, str]] = Field(
21
+ headers: dict[str, str] | None = Field(
21
22
  description="Optional headers to include in the request",
22
23
  default=None,
23
24
  )
24
- params: Optional[Dict[str, Any]] = Field(
25
+ params: dict[str, Any] | None = Field(
25
26
  description="Optional query parameters to include in the request",
26
27
  default=None,
27
28
  )
28
- timeout: Optional[float] = Field(
29
+ timeout: float | None = Field(
29
30
  description="Request timeout in seconds (default: 30)",
30
31
  default=30.0,
31
32
  )
@@ -51,14 +52,14 @@ class HttpPut(HttpBaseTool):
51
52
  "Returns the response content as text. "
52
53
  "Use this when you need to update or replace data on web APIs."
53
54
  )
54
- args_schema: Type[BaseModel] = HttpPutInput
55
+ args_schema: type[BaseModel] = HttpPutInput
55
56
 
56
57
  async def _arun(
57
58
  self,
58
59
  url: str,
59
- data: Optional[Union[Dict[str, Any], str]] = None,
60
- headers: Optional[Dict[str, str]] = None,
61
- params: Optional[Dict[str, Any]] = None,
60
+ data: dict[str, Any] | str | None = None,
61
+ headers: dict[str, str] | None = None,
62
+ params: dict[str, Any] | None = None,
62
63
  timeout: float = 30.0,
63
64
  **kwargs,
64
65
  ) -> str:
@@ -100,12 +101,16 @@ class HttpPut(HttpBaseTool):
100
101
  # Return response content
101
102
  return f"Status: {response.status_code}\nContent: {response.text}"
102
103
 
103
- except httpx.TimeoutException:
104
- return f"Error: Request to {url} timed out after {timeout} seconds"
105
- except httpx.HTTPStatusError as e:
106
- return f"Error: HTTP {e.response.status_code} - {e.response.text}"
107
- except httpx.RequestError as e:
108
- return f"Error: Failed to connect to {url} - {str(e)}"
109
- except Exception as e:
110
- logger.error(f"Unexpected error in HTTP PUT request: {e}")
111
- return f"Error: Unexpected error occurred - {str(e)}"
104
+ except httpx.TimeoutException as exc:
105
+ raise ToolException(
106
+ f"Request to {url} timed out after {timeout} seconds"
107
+ ) from exc
108
+ except httpx.HTTPStatusError as exc:
109
+ raise ToolException(
110
+ f"HTTP {exc.response.status_code} - {exc.response.text}"
111
+ ) from exc
112
+ except httpx.RequestError as exc:
113
+ raise ToolException(f"Failed to connect to {url} - {str(exc)}") from exc
114
+ except Exception as exc: # noqa: BLE001
115
+ logger.error("Unexpected error in HTTP PUT request", exc_info=exc)
116
+ raise ToolException(f"Unexpected error occurred - {str(exc)}") from exc
@@ -1,7 +1,6 @@
1
1
  import logging
2
- from typing import Any, List, Optional, TypedDict
2
+ from typing import Any, TypedDict
3
3
 
4
- from intentkit.abstracts.skill import SkillStoreABC
5
4
  from intentkit.skills.base import SkillConfig, SkillState
6
5
  from intentkit.skills.lifi.base import LiFiBaseTool
7
6
  from intentkit.skills.lifi.token_execute import TokenExecute
@@ -23,15 +22,14 @@ class Config(SkillConfig):
23
22
  """Configuration for LiFi skills."""
24
23
 
25
24
  states: SkillStates
26
- default_slippage: Optional[float] = 0.03
27
- allowed_chains: Optional[List[str]] = None
28
- max_execution_time: Optional[int] = 300
25
+ default_slippage: float | None = 0.03
26
+ allowed_chains: list[str] | None = None
27
+ max_execution_time: int | None = 300
29
28
 
30
29
 
31
30
  async def get_skills(
32
31
  config: "Config",
33
32
  is_private: bool,
34
- store: SkillStoreABC,
35
33
  **_: Any,
36
34
  ) -> list[LiFiBaseTool]:
37
35
  """Get all LiFi skills."""
@@ -60,7 +58,7 @@ async def get_skills(
60
58
  skills: list[LiFiBaseTool] = []
61
59
  for name in available_skills:
62
60
  try:
63
- skill = get_lifi_skill(name, store, config)
61
+ skill = get_lifi_skill(name, config)
64
62
  skills.append(skill)
65
63
  logger.info(f"[LiFi_Skills] Successfully loaded skill: {name}")
66
64
  except Exception as e:
@@ -73,7 +71,6 @@ async def get_skills(
73
71
 
74
72
  def get_lifi_skill(
75
73
  name: str,
76
- store: SkillStoreABC,
77
74
  config: Config,
78
75
  ) -> LiFiBaseTool:
79
76
  """Get a LiFi skill by name."""
@@ -108,7 +105,6 @@ def get_lifi_skill(
108
105
  logger.info(f"[LiFi_Skills] Allowed chains: {allowed_chains}")
109
106
 
110
107
  _cache[cache_key] = TokenQuote(
111
- skill_store=store,
112
108
  default_slippage=default_slippage,
113
109
  allowed_chains=allowed_chains,
114
110
  )
@@ -129,7 +125,6 @@ def get_lifi_skill(
129
125
  )
130
126
 
131
127
  _cache[cache_key] = TokenExecute(
132
- skill_store=store,
133
128
  default_slippage=default_slippage,
134
129
  allowed_chains=allowed_chains,
135
130
  max_execution_time=max_execution_time,
@@ -1,8 +1,5 @@
1
- from typing import Type
2
-
3
1
  from pydantic import BaseModel, Field
4
2
 
5
- from intentkit.abstracts.skill import SkillStoreABC
6
3
  from intentkit.skills.base import IntentKitSkill
7
4
 
8
5
 
@@ -11,10 +8,7 @@ class LiFiBaseTool(IntentKitSkill):
11
8
 
12
9
  name: str = Field(description="The name of the tool")
13
10
  description: str = Field(description="A description of what the tool does")
14
- args_schema: Type[BaseModel]
15
- skill_store: SkillStoreABC = Field(
16
- description="The skill store for persisting data"
17
- )
11
+ args_schema: type[BaseModel]
18
12
 
19
13
  @property
20
14
  def category(self) -> str:
@@ -1,12 +1,11 @@
1
1
  import asyncio
2
- from typing import Any, Dict, List, Optional, Type
2
+ from typing import Any
3
3
 
4
4
  import httpx
5
5
  from coinbase_agentkit import CdpEvmWalletProvider
6
6
  from pydantic import BaseModel, Field
7
7
  from web3 import Web3
8
8
 
9
- from intentkit.abstracts.skill import SkillStoreABC
10
9
  from intentkit.clients import get_wallet_provider as get_agent_wallet_provider
11
10
  from intentkit.models.agent import Agent
12
11
  from intentkit.skills.lifi.base import LiFiBaseTool
@@ -64,36 +63,34 @@ class TokenExecute(LiFiBaseTool):
64
63
  "Use token_quote first to check rates and fees before executing.\n"
65
64
  "Supports all major chains like Ethereum, Polygon, Arbitrum, Optimism, Base, and more."
66
65
  )
67
- args_schema: Type[BaseModel] = TokenExecuteInput
66
+ args_schema: type[BaseModel] = TokenExecuteInput
68
67
  api_url: str = LIFI_API_URL
69
68
 
70
69
  # Configuration options
71
70
  default_slippage: float = 0.03
72
- allowed_chains: Optional[List[str]] = None
71
+ allowed_chains: list[str] | None = None
73
72
  max_execution_time: int = 300
74
- quote_tool: Optional[TokenQuote] = Field(default=None, exclude=True)
73
+ quote_tool: TokenQuote | None = Field(default=None, exclude=True)
75
74
 
76
75
  def __init__(
77
76
  self,
78
- skill_store: SkillStoreABC,
79
77
  default_slippage: float = 0.03,
80
- allowed_chains: Optional[List[str]] = None,
78
+ allowed_chains: list[str] | None = None,
81
79
  max_execution_time: int = 300,
82
80
  ) -> None:
83
81
  """Initialize the TokenExecute skill with configuration options."""
84
- super().__init__(skill_store=skill_store)
82
+ super().__init__()
85
83
  self.default_slippage = default_slippage
86
84
  self.allowed_chains = allowed_chains
87
85
  self.max_execution_time = max_execution_time
88
86
  # Initialize quote tool if not set
89
87
  if not self.quote_tool:
90
88
  self.quote_tool = TokenQuote(
91
- skill_store=skill_store,
92
89
  default_slippage=default_slippage,
93
90
  allowed_chains=allowed_chains,
94
91
  )
95
92
 
96
- def _format_quote_result(self, data: Dict[str, Any]) -> str:
93
+ def _format_quote_result(self, data: dict[str, Any]) -> str:
97
94
  """Format the quote result in a readable format."""
98
95
  if self.quote_tool is None:
99
96
  raise RuntimeError("Quote tool is not initialized")
@@ -107,7 +104,7 @@ class TokenExecute(LiFiBaseTool):
107
104
  from_token: str,
108
105
  to_token: str,
109
106
  from_amount: str,
110
- slippage: Optional[float] = None,
107
+ slippage: float | None = None,
111
108
  **kwargs,
112
109
  ) -> str:
113
110
  """Execute a token transfer."""
@@ -211,7 +208,7 @@ class TokenExecute(LiFiBaseTool):
211
208
  from_amount: str,
212
209
  slippage: float,
213
210
  from_address: str,
214
- ) -> Dict[str, Any] | str:
211
+ ) -> dict[str, Any] | str:
215
212
  """Get quote from LiFi API."""
216
213
  api_params = build_quote_params(
217
214
  from_chain,
@@ -253,8 +250,8 @@ class TokenExecute(LiFiBaseTool):
253
250
  return data
254
251
 
255
252
  async def _handle_token_approval(
256
- self, wallet_provider: CdpEvmWalletProvider, quote_data: Dict[str, Any]
257
- ) -> Optional[str]:
253
+ self, wallet_provider: CdpEvmWalletProvider, quote_data: dict[str, Any]
254
+ ) -> str | None:
258
255
  """Handle ERC20 token approval if needed."""
259
256
  estimate = quote_data.get("estimate", {})
260
257
  approval_address = estimate.get("approvalAddress")
@@ -279,7 +276,7 @@ class TokenExecute(LiFiBaseTool):
279
276
  async def _execute_transfer_transaction(
280
277
  self,
281
278
  wallet_provider: CdpEvmWalletProvider,
282
- quote_data: Dict[str, Any],
279
+ quote_data: dict[str, Any],
283
280
  from_address: str,
284
281
  ) -> str:
285
282
  """Execute the main transfer transaction."""
@@ -313,7 +310,7 @@ class TokenExecute(LiFiBaseTool):
313
310
  tx_hash: str,
314
311
  from_chain: str,
315
312
  to_chain: str,
316
- quote_data: Dict[str, Any],
313
+ quote_data: dict[str, Any],
317
314
  ) -> str:
318
315
  """Finalize transfer and return formatted result."""
319
316
  self.logger.info(f"Transaction sent: {tx_hash}")
@@ -420,7 +417,7 @@ class TokenExecute(LiFiBaseTool):
420
417
  token_address: str,
421
418
  approval_address: str,
422
419
  amount: str,
423
- ) -> Optional[str]:
420
+ ) -> str | None:
424
421
  """Check if token allowance is sufficient and set approval if needed."""
425
422
  try:
426
423
  # Normalize addresses
@@ -1,9 +1,8 @@
1
- from typing import Any, Dict, List, Optional, Type
1
+ from typing import Any
2
2
 
3
3
  import httpx
4
4
  from pydantic import BaseModel, Field
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
7
6
  from intentkit.skills.lifi.base import LiFiBaseTool
8
7
  from intentkit.skills.lifi.utils import (
9
8
  LIFI_API_URL,
@@ -53,21 +52,20 @@ class TokenQuote(LiFiBaseTool):
53
52
  "Use this tool to check rates, fees, and estimated time for token transfers without executing them.\n"
54
53
  "Supports all major chains like Ethereum, Polygon, Arbitrum, Optimism, Base, and more."
55
54
  )
56
- args_schema: Type[BaseModel] = TokenQuoteInput
55
+ args_schema: type[BaseModel] = TokenQuoteInput
57
56
  api_url: str = LIFI_API_URL
58
57
 
59
58
  # Configuration options
60
59
  default_slippage: float = 0.03
61
- allowed_chains: Optional[List[str]] = None
60
+ allowed_chains: list[str] | None = None
62
61
 
63
62
  def __init__(
64
63
  self,
65
- skill_store: SkillStoreABC,
66
64
  default_slippage: float = 0.03,
67
- allowed_chains: Optional[List[str]] = None,
65
+ allowed_chains: list[str] | None = None,
68
66
  ) -> None:
69
67
  """Initialize the TokenQuote skill with configuration options."""
70
- super().__init__(skill_store=skill_store)
68
+ super().__init__()
71
69
  self.default_slippage = default_slippage
72
70
  self.allowed_chains = allowed_chains
73
71
 
@@ -78,7 +76,7 @@ class TokenQuote(LiFiBaseTool):
78
76
  from_token: str,
79
77
  to_token: str,
80
78
  from_amount: str,
81
- slippage: Optional[float] = None,
79
+ slippage: float | None = None,
82
80
  **kwargs,
83
81
  ) -> str:
84
82
  """Get a quote for token transfer."""
@@ -140,7 +138,7 @@ class TokenQuote(LiFiBaseTool):
140
138
  self.logger.error("LiFi_Error: %s", str(e))
141
139
  return f"An unexpected error occurred: {str(e)}"
142
140
 
143
- def _format_quote_result(self, data: Dict[str, Any]) -> str:
141
+ def _format_quote_result(self, data: dict[str, Any]) -> str:
144
142
  """Format quote result into human-readable text."""
145
143
  try:
146
144
  # Get basic info
@@ -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, Dict, List, Optional, Tuple
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: Optional[List[str]] = None,
76
- ) -> Optional[str]:
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
- ) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
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: Optional[str] = None,
345
- ) -> Dict[str, Any]:
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) -> Optional[int]:
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: Dict[str, Any],
413
- wallet_address: Optional[str] = None,
414
- ) -> Dict[str, Any]:
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: Dict[str, Any] = {
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: Dict[str, Any]) -> Dict[str, Any]:
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: Dict[str, Any]) -> Tuple[str, str]:
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: List[Dict[str, Any]] = []
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: Dict[str, Any]) -> str:
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: Optional[Dict[str, str]] = None
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,9 +1,9 @@
1
1
  """Wallet Portfolio Skills for IntentKit."""
2
2
 
3
3
  import logging
4
- from typing import Dict, List, NotRequired, TypedDict
4
+ from typing import NotRequired, TypedDict
5
5
 
6
- from intentkit.abstracts.skill import SkillStoreABC
6
+ from intentkit.config.config import config as system_config
7
7
  from intentkit.skills.base import SkillConfig, SkillState
8
8
  from intentkit.skills.moralis.base import WalletBaseTool
9
9
  from intentkit.skills.moralis.fetch_chain_portfolio import FetchChainPortfolio
@@ -28,21 +28,19 @@ class Config(SkillConfig):
28
28
 
29
29
  api_key: str
30
30
  states: SkillStates
31
- supported_chains: NotRequired[Dict[str, bool]] = {"evm": True, "solana": True}
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
- store: SkillStoreABC,
38
37
  **_,
39
- ) -> List[WalletBaseTool]:
38
+ ) -> list[WalletBaseTool]:
40
39
  """Get all Wallet Portfolio skills.
41
40
 
42
41
  Args:
43
42
  config: Skill configuration
44
43
  is_private: Whether the request is from an authenticated user
45
- store: Skill store for persistence
46
44
  chain_provider: Optional chain provider for blockchain interactions
47
45
  **_: Additional arguments
48
46
 
@@ -67,12 +65,12 @@ async def get_skills(
67
65
  if config.get("api_key_provider") == "agent_owner":
68
66
  api_key = config.get("api_key")
69
67
  else:
70
- api_key = store.get_system_config("moralis_api_key")
68
+ api_key = system_config.moralis_api_key
71
69
 
72
70
  # Get each skill using the getter
73
71
  result = []
74
72
  for name in available_skills:
75
- skill = get_wallet_skill(name, api_key, store)
73
+ skill = get_wallet_skill(name, api_key)
76
74
  if skill:
77
75
  result.append(skill)
78
76
  return result
@@ -81,7 +79,6 @@ async def get_skills(
81
79
  def get_wallet_skill(
82
80
  name: str,
83
81
  api_key: str,
84
- store: SkillStoreABC,
85
82
  ) -> WalletBaseTool:
86
83
  """Get a specific Wallet Portfolio skill by name.
87
84
 
@@ -106,5 +103,4 @@ def get_wallet_skill(
106
103
 
107
104
  return skill_classes[name](
108
105
  api_key=api_key,
109
- skill_store=store,
110
106
  )
@@ -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: Dict = None) -> Dict:
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
- ) -> Dict:
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
- ) -> Dict:
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
- ) -> Dict:
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") -> Dict:
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
- ) -> Dict:
268
+ ) -> dict:
270
269
  """Get token price by mint address.
271
270
 
272
271
  Args: