intentkit 0.6.13.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 (385) 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 +14 -7
  5. intentkit/abstracts/skill.py +6 -144
  6. intentkit/abstracts/twitter.py +4 -5
  7. intentkit/clients/__init__.py +5 -2
  8. intentkit/clients/cdp.py +101 -141
  9. intentkit/clients/twitter.py +83 -62
  10. intentkit/clients/web3.py +29 -0
  11. intentkit/config/config.py +8 -5
  12. intentkit/core/agent.py +472 -195
  13. intentkit/core/asset.py +253 -0
  14. intentkit/core/chat.py +51 -0
  15. intentkit/core/client.py +1 -1
  16. intentkit/core/credit.py +460 -130
  17. intentkit/core/engine.py +262 -233
  18. intentkit/core/node.py +15 -16
  19. intentkit/core/prompt.py +62 -28
  20. intentkit/core/scheduler.py +92 -0
  21. intentkit/core/statistics.py +168 -0
  22. intentkit/models/agent.py +1096 -949
  23. intentkit/models/agent_data.py +68 -38
  24. intentkit/models/agent_public.json +98 -0
  25. intentkit/models/agent_schema.json +54 -439
  26. intentkit/models/app_setting.py +96 -33
  27. intentkit/models/chat.py +74 -27
  28. intentkit/models/conversation.py +8 -8
  29. intentkit/models/credit.py +362 -74
  30. intentkit/models/db.py +26 -8
  31. intentkit/models/db_mig.py +2 -2
  32. intentkit/models/llm.csv +28 -0
  33. intentkit/models/llm.py +185 -350
  34. intentkit/models/redis.py +6 -4
  35. intentkit/models/skill.py +186 -72
  36. intentkit/models/skills.csv +174 -0
  37. intentkit/models/user.py +82 -24
  38. intentkit/skills/acolyt/__init__.py +2 -9
  39. intentkit/skills/acolyt/ask.py +3 -4
  40. intentkit/skills/acolyt/base.py +4 -9
  41. intentkit/skills/acolyt/schema.json +4 -3
  42. intentkit/skills/aixbt/__init__.py +2 -13
  43. intentkit/skills/aixbt/base.py +1 -7
  44. intentkit/skills/aixbt/projects.py +14 -15
  45. intentkit/skills/aixbt/schema.json +4 -4
  46. intentkit/skills/allora/__init__.py +2 -9
  47. intentkit/skills/allora/base.py +4 -9
  48. intentkit/skills/allora/price.py +3 -4
  49. intentkit/skills/allora/schema.json +3 -2
  50. intentkit/skills/base.py +248 -85
  51. intentkit/skills/basename/__init__.py +51 -0
  52. intentkit/skills/basename/base.py +11 -0
  53. intentkit/skills/basename/basename.svg +11 -0
  54. intentkit/skills/basename/schema.json +58 -0
  55. intentkit/skills/carv/__init__.py +115 -121
  56. intentkit/skills/carv/base.py +184 -185
  57. intentkit/skills/carv/fetch_news.py +3 -3
  58. intentkit/skills/carv/onchain_query.py +4 -4
  59. intentkit/skills/carv/schema.json +134 -137
  60. intentkit/skills/carv/token_info_and_price.py +5 -5
  61. intentkit/skills/casino/README.md +254 -0
  62. intentkit/skills/casino/__init__.py +86 -0
  63. intentkit/skills/casino/base.py +17 -0
  64. intentkit/skills/casino/casino.png +0 -0
  65. intentkit/skills/casino/deck_draw.py +127 -0
  66. intentkit/skills/casino/deck_shuffle.py +118 -0
  67. intentkit/skills/casino/dice_roll.py +100 -0
  68. intentkit/skills/casino/schema.json +77 -0
  69. intentkit/skills/casino/utils.py +107 -0
  70. intentkit/skills/cdp/__init__.py +22 -84
  71. intentkit/skills/cdp/base.py +1 -7
  72. intentkit/skills/cdp/schema.json +11 -314
  73. intentkit/skills/chainlist/__init__.py +2 -7
  74. intentkit/skills/chainlist/base.py +1 -7
  75. intentkit/skills/chainlist/chain_lookup.py +18 -18
  76. intentkit/skills/chainlist/schema.json +3 -5
  77. intentkit/skills/common/__init__.py +2 -9
  78. intentkit/skills/common/base.py +1 -7
  79. intentkit/skills/common/current_time.py +1 -2
  80. intentkit/skills/common/schema.json +2 -2
  81. intentkit/skills/cookiefun/__init__.py +6 -9
  82. intentkit/skills/cookiefun/base.py +2 -7
  83. intentkit/skills/cookiefun/get_account_details.py +7 -7
  84. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  85. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  86. intentkit/skills/cookiefun/get_sectors.py +3 -3
  87. intentkit/skills/cookiefun/schema.json +1 -3
  88. intentkit/skills/cookiefun/search_accounts.py +9 -9
  89. intentkit/skills/cryptocompare/__init__.py +7 -24
  90. intentkit/skills/cryptocompare/api.py +2 -3
  91. intentkit/skills/cryptocompare/base.py +11 -25
  92. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  93. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  94. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  95. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  96. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  97. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  98. intentkit/skills/cryptocompare/schema.json +3 -3
  99. intentkit/skills/cryptopanic/__init__.py +7 -10
  100. intentkit/skills/cryptopanic/base.py +51 -55
  101. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  102. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  103. intentkit/skills/cryptopanic/schema.json +105 -103
  104. intentkit/skills/dapplooker/__init__.py +2 -9
  105. intentkit/skills/dapplooker/base.py +4 -9
  106. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  107. intentkit/skills/dapplooker/schema.json +3 -5
  108. intentkit/skills/defillama/__init__.py +24 -74
  109. intentkit/skills/defillama/api.py +6 -9
  110. intentkit/skills/defillama/base.py +11 -21
  111. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  112. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  113. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  114. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  115. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  116. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  117. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  118. intentkit/skills/defillama/config/chains.py +1 -3
  119. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  120. intentkit/skills/defillama/schema.json +5 -1
  121. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  122. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  123. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  124. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  125. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  126. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  127. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  128. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  129. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  130. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  131. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  132. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  133. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  134. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  135. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  136. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  137. intentkit/skills/dexscreener/README.md +154 -0
  138. intentkit/skills/dexscreener/__init__.py +97 -93
  139. intentkit/skills/dexscreener/base.py +125 -133
  140. intentkit/skills/dexscreener/get_pair_info.py +158 -0
  141. intentkit/skills/dexscreener/get_token_pairs.py +165 -0
  142. intentkit/skills/dexscreener/get_tokens_info.py +212 -0
  143. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  144. intentkit/skills/dexscreener/schema.json +91 -48
  145. intentkit/skills/dexscreener/search_token.py +182 -321
  146. intentkit/skills/dexscreener/utils.py +420 -0
  147. intentkit/skills/dune_analytics/__init__.py +7 -9
  148. intentkit/skills/dune_analytics/base.py +48 -52
  149. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  150. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  151. intentkit/skills/dune_analytics/schema.json +104 -99
  152. intentkit/skills/elfa/__init__.py +5 -18
  153. intentkit/skills/elfa/base.py +10 -14
  154. intentkit/skills/elfa/mention.py +19 -21
  155. intentkit/skills/elfa/schema.json +3 -2
  156. intentkit/skills/elfa/stats.py +4 -4
  157. intentkit/skills/elfa/tokens.py +12 -12
  158. intentkit/skills/elfa/utils.py +26 -28
  159. intentkit/skills/enso/__init__.py +11 -31
  160. intentkit/skills/enso/base.py +50 -35
  161. intentkit/skills/enso/best_yield.py +16 -24
  162. intentkit/skills/enso/networks.py +6 -11
  163. intentkit/skills/enso/prices.py +11 -13
  164. intentkit/skills/enso/route.py +34 -38
  165. intentkit/skills/enso/schema.json +3 -2
  166. intentkit/skills/enso/tokens.py +29 -38
  167. intentkit/skills/enso/wallet.py +76 -191
  168. intentkit/skills/erc20/__init__.py +50 -0
  169. intentkit/skills/erc20/base.py +11 -0
  170. intentkit/skills/erc20/erc20.svg +5 -0
  171. intentkit/skills/erc20/schema.json +74 -0
  172. intentkit/skills/erc721/__init__.py +53 -0
  173. intentkit/skills/erc721/base.py +11 -0
  174. intentkit/skills/erc721/erc721.svg +5 -0
  175. intentkit/skills/erc721/schema.json +90 -0
  176. intentkit/skills/firecrawl/README.md +11 -5
  177. intentkit/skills/firecrawl/__init__.py +5 -18
  178. intentkit/skills/firecrawl/base.py +4 -11
  179. intentkit/skills/firecrawl/clear.py +4 -8
  180. intentkit/skills/firecrawl/crawl.py +19 -19
  181. intentkit/skills/firecrawl/query.py +4 -3
  182. intentkit/skills/firecrawl/schema.json +6 -8
  183. intentkit/skills/firecrawl/scrape.py +150 -40
  184. intentkit/skills/firecrawl/utils.py +50 -42
  185. intentkit/skills/github/__init__.py +2 -7
  186. intentkit/skills/github/base.py +1 -7
  187. intentkit/skills/github/github_search.py +1 -2
  188. intentkit/skills/github/schema.json +3 -4
  189. intentkit/skills/heurist/__init__.py +8 -27
  190. intentkit/skills/heurist/base.py +4 -9
  191. intentkit/skills/heurist/image_generation_animagine_xl.py +12 -13
  192. intentkit/skills/heurist/image_generation_arthemy_comics.py +12 -13
  193. intentkit/skills/heurist/image_generation_arthemy_real.py +12 -13
  194. intentkit/skills/heurist/image_generation_braindance.py +12 -13
  195. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +12 -13
  196. intentkit/skills/heurist/image_generation_flux_1_dev.py +12 -13
  197. intentkit/skills/heurist/image_generation_sdxl.py +12 -13
  198. intentkit/skills/heurist/schema.json +2 -2
  199. intentkit/skills/http/__init__.py +4 -15
  200. intentkit/skills/http/base.py +1 -7
  201. intentkit/skills/http/get.py +21 -16
  202. intentkit/skills/http/post.py +23 -18
  203. intentkit/skills/http/put.py +23 -18
  204. intentkit/skills/http/schema.json +4 -5
  205. intentkit/skills/lifi/__init__.py +8 -13
  206. intentkit/skills/lifi/base.py +1 -7
  207. intentkit/skills/lifi/schema.json +17 -8
  208. intentkit/skills/lifi/token_execute.py +36 -30
  209. intentkit/skills/lifi/token_quote.py +8 -10
  210. intentkit/skills/lifi/utils.py +104 -51
  211. intentkit/skills/moralis/__init__.py +6 -10
  212. intentkit/skills/moralis/api.py +6 -7
  213. intentkit/skills/moralis/base.py +5 -10
  214. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  215. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  216. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  217. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  218. intentkit/skills/moralis/schema.json +7 -2
  219. intentkit/skills/morpho/__init__.py +52 -0
  220. intentkit/skills/morpho/base.py +11 -0
  221. intentkit/skills/morpho/morpho.svg +12 -0
  222. intentkit/skills/morpho/schema.json +73 -0
  223. intentkit/skills/nation/__init__.py +4 -9
  224. intentkit/skills/nation/base.py +5 -10
  225. intentkit/skills/nation/nft_check.py +3 -4
  226. intentkit/skills/nation/schema.json +4 -3
  227. intentkit/skills/onchain.py +23 -0
  228. intentkit/skills/openai/__init__.py +17 -18
  229. intentkit/skills/openai/base.py +10 -14
  230. intentkit/skills/openai/dalle_image_generation.py +3 -8
  231. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  232. intentkit/skills/openai/gpt_image_generation.py +4 -8
  233. intentkit/skills/openai/gpt_image_mini_generator.py +91 -0
  234. intentkit/skills/openai/gpt_image_to_image.py +4 -8
  235. intentkit/skills/openai/image_to_text.py +3 -7
  236. intentkit/skills/openai/schema.json +34 -3
  237. intentkit/skills/portfolio/__init__.py +11 -35
  238. intentkit/skills/portfolio/base.py +33 -19
  239. intentkit/skills/portfolio/schema.json +3 -5
  240. intentkit/skills/portfolio/token_balances.py +21 -21
  241. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  242. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  243. intentkit/skills/portfolio/wallet_history.py +31 -31
  244. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  245. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  246. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  247. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  248. intentkit/skills/portfolio/wallet_stats.py +3 -3
  249. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  250. intentkit/skills/pyth/__init__.py +50 -0
  251. intentkit/skills/pyth/base.py +11 -0
  252. intentkit/skills/pyth/pyth.svg +6 -0
  253. intentkit/skills/pyth/schema.json +75 -0
  254. intentkit/skills/skills.toml +40 -0
  255. intentkit/skills/slack/__init__.py +5 -17
  256. intentkit/skills/slack/base.py +3 -9
  257. intentkit/skills/slack/get_channel.py +8 -8
  258. intentkit/skills/slack/get_message.py +9 -9
  259. intentkit/skills/slack/schedule_message.py +5 -5
  260. intentkit/skills/slack/schema.json +2 -2
  261. intentkit/skills/slack/send_message.py +3 -5
  262. intentkit/skills/supabase/__init__.py +7 -23
  263. intentkit/skills/supabase/base.py +9 -13
  264. intentkit/skills/supabase/delete_data.py +5 -6
  265. intentkit/skills/supabase/fetch_data.py +13 -14
  266. intentkit/skills/supabase/insert_data.py +5 -6
  267. intentkit/skills/supabase/invoke_function.py +7 -8
  268. intentkit/skills/supabase/schema.json +2 -3
  269. intentkit/skills/supabase/update_data.py +7 -8
  270. intentkit/skills/supabase/upsert_data.py +5 -6
  271. intentkit/skills/superfluid/__init__.py +53 -0
  272. intentkit/skills/superfluid/base.py +11 -0
  273. intentkit/skills/superfluid/schema.json +89 -0
  274. intentkit/skills/superfluid/superfluid.svg +6 -0
  275. intentkit/skills/system/__init__.py +7 -24
  276. intentkit/skills/system/add_autonomous_task.py +10 -12
  277. intentkit/skills/system/delete_autonomous_task.py +2 -2
  278. intentkit/skills/system/edit_autonomous_task.py +14 -18
  279. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  280. intentkit/skills/system/read_agent_api_key.py +6 -4
  281. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  282. intentkit/skills/system/schema.json +6 -8
  283. intentkit/skills/tavily/__init__.py +3 -12
  284. intentkit/skills/tavily/base.py +4 -9
  285. intentkit/skills/tavily/schema.json +3 -5
  286. intentkit/skills/tavily/tavily_extract.py +2 -4
  287. intentkit/skills/tavily/tavily_search.py +4 -6
  288. intentkit/skills/token/__init__.py +5 -10
  289. intentkit/skills/token/base.py +7 -11
  290. intentkit/skills/token/erc20_transfers.py +19 -19
  291. intentkit/skills/token/schema.json +3 -6
  292. intentkit/skills/token/token_analytics.py +3 -3
  293. intentkit/skills/token/token_price.py +13 -13
  294. intentkit/skills/token/token_search.py +9 -9
  295. intentkit/skills/twitter/__init__.py +11 -35
  296. intentkit/skills/twitter/base.py +23 -35
  297. intentkit/skills/twitter/follow_user.py +3 -7
  298. intentkit/skills/twitter/get_mentions.py +6 -13
  299. intentkit/skills/twitter/get_timeline.py +5 -13
  300. intentkit/skills/twitter/get_user_by_username.py +3 -7
  301. intentkit/skills/twitter/get_user_tweets.py +6 -14
  302. intentkit/skills/twitter/like_tweet.py +3 -7
  303. intentkit/skills/twitter/post_tweet.py +23 -12
  304. intentkit/skills/twitter/reply_tweet.py +21 -12
  305. intentkit/skills/twitter/retweet.py +3 -7
  306. intentkit/skills/twitter/schema.json +1 -0
  307. intentkit/skills/twitter/search_tweets.py +5 -13
  308. intentkit/skills/unrealspeech/__init__.py +2 -7
  309. intentkit/skills/unrealspeech/base.py +2 -8
  310. intentkit/skills/unrealspeech/schema.json +2 -5
  311. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  312. intentkit/skills/venice_audio/__init__.py +98 -106
  313. intentkit/skills/venice_audio/base.py +117 -121
  314. intentkit/skills/venice_audio/input.py +41 -41
  315. intentkit/skills/venice_audio/schema.json +151 -152
  316. intentkit/skills/venice_audio/venice_audio.py +38 -21
  317. intentkit/skills/venice_image/__init__.py +147 -154
  318. intentkit/skills/venice_image/api.py +138 -138
  319. intentkit/skills/venice_image/base.py +185 -192
  320. intentkit/skills/venice_image/config.py +33 -35
  321. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  322. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  323. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  324. intentkit/skills/venice_image/image_generation/image_generation_base.py +9 -9
  325. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  326. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  327. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  328. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  329. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  330. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  331. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  332. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  333. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  334. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  335. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  336. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  337. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  338. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  339. intentkit/skills/venice_image/schema.json +267 -267
  340. intentkit/skills/venice_image/utils.py +77 -78
  341. intentkit/skills/web_scraper/__init__.py +5 -18
  342. intentkit/skills/web_scraper/base.py +21 -7
  343. intentkit/skills/web_scraper/document_indexer.py +7 -6
  344. intentkit/skills/web_scraper/schema.json +2 -6
  345. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  346. intentkit/skills/web_scraper/utils.py +62 -63
  347. intentkit/skills/web_scraper/website_indexer.py +17 -19
  348. intentkit/skills/weth/__init__.py +49 -0
  349. intentkit/skills/weth/base.py +11 -0
  350. intentkit/skills/weth/schema.json +58 -0
  351. intentkit/skills/weth/weth.svg +6 -0
  352. intentkit/skills/wow/__init__.py +51 -0
  353. intentkit/skills/wow/base.py +11 -0
  354. intentkit/skills/wow/schema.json +89 -0
  355. intentkit/skills/wow/wow.svg +7 -0
  356. intentkit/skills/x402/__init__.py +61 -0
  357. intentkit/skills/x402/ask_agent.py +98 -0
  358. intentkit/skills/x402/base.py +99 -0
  359. intentkit/skills/x402/http_request.py +117 -0
  360. intentkit/skills/x402/schema.json +45 -0
  361. intentkit/skills/x402/x402.webp +0 -0
  362. intentkit/skills/xmtp/__init__.py +4 -15
  363. intentkit/skills/xmtp/base.py +61 -2
  364. intentkit/skills/xmtp/price.py +18 -13
  365. intentkit/skills/xmtp/schema.json +69 -71
  366. intentkit/skills/xmtp/swap.py +22 -25
  367. intentkit/skills/xmtp/transfer.py +71 -32
  368. intentkit/utils/chain.py +3 -3
  369. intentkit/utils/error.py +14 -1
  370. intentkit/utils/logging.py +2 -4
  371. intentkit/utils/s3.py +59 -7
  372. intentkit/utils/schema.py +100 -0
  373. intentkit/utils/slack_alert.py +7 -8
  374. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/METADATA +14 -16
  375. intentkit-0.8.17.dist-info/RECORD +466 -0
  376. intentkit/abstracts/exception.py +0 -9
  377. intentkit/core/skill.py +0 -200
  378. intentkit/models/generator.py +0 -347
  379. intentkit/skills/cdp/get_balance.py +0 -110
  380. intentkit/skills/cdp/swap.py +0 -121
  381. intentkit/skills/moralis/tests/__init__.py +0 -0
  382. intentkit/skills/moralis/tests/test_wallet.py +0 -511
  383. intentkit-0.6.13.dev2.dist-info/RECORD +0 -409
  384. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/WHEEL +0 -0
  385. {intentkit-0.6.13.dev2.dist-info → intentkit-0.8.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,14 +1,8 @@
1
- from typing import Type
2
-
3
1
  import httpx
4
- from langchain.tools.base import ToolException
2
+ from langchain_core.tools.base import ToolException
5
3
  from pydantic import BaseModel, Field
6
4
 
7
- from intentkit.skills.enso.base import (
8
- EnsoBaseTool,
9
- base_url,
10
- default_chain_id,
11
- )
5
+ from intentkit.skills.enso.base import EnsoBaseTool, base_url
12
6
 
13
7
  # Actual Enso output types
14
8
  # class UnderlyingToken(BaseModel):
@@ -50,9 +44,9 @@ from intentkit.skills.enso.base import (
50
44
 
51
45
 
52
46
  class EnsoGetTokensInput(BaseModel):
53
- chainId: int = Field(
54
- default_chain_id,
55
- description="The blockchain chain ID",
47
+ chainId: int | None = Field(
48
+ None,
49
+ description="The blockchain chain ID. Defaults to the agent's configured network.",
56
50
  )
57
51
  protocolSlug: str | None = Field(
58
52
  None,
@@ -110,7 +104,10 @@ class TokenResponseCompact(BaseModel):
110
104
 
111
105
 
112
106
  class EnsoGetTokensOutput(BaseModel):
113
- res: list[TokenResponseCompact] | None
107
+ res: list[TokenResponseCompact] = Field(
108
+ default_factory=list,
109
+ description="List of token information entries",
110
+ )
114
111
 
115
112
 
116
113
  class EnsoGetTokens(EnsoBaseTool):
@@ -134,11 +131,11 @@ class EnsoGetTokens(EnsoBaseTool):
134
131
  "Enso Finance Token Information Tool: Retrieves detailed token information from the Enso Finance API, "
135
132
  "including APY, symbol, address, protocol slug, token type, and underlying tokens."
136
133
  )
137
- args_schema: Type[BaseModel] = EnsoGetTokensInput
134
+ args_schema: type[BaseModel] = EnsoGetTokensInput
138
135
 
139
136
  async def _arun(
140
137
  self,
141
- chainId: int = default_chain_id,
138
+ chainId: int | None = None,
142
139
  protocolSlug: str | None = None,
143
140
  **kwargs,
144
141
  ) -> EnsoGetTokensOutput:
@@ -155,16 +152,17 @@ class EnsoGetTokens(EnsoBaseTool):
155
152
  url = f"{base_url}/api/v1/tokens"
156
153
 
157
154
  context = self.get_context()
158
- agent_id = context.agent_id
155
+ resolved_chain_id = self.resolve_chain_id(context, chainId)
159
156
  api_token = self.get_api_token(context)
160
157
  main_tokens = self.get_main_tokens(context)
158
+ main_tokens_upper = {token.upper() for token in main_tokens}
161
159
  headers = {
162
160
  "accept": "application/json",
163
161
  "Authorization": f"Bearer {api_token}",
164
162
  }
165
163
 
166
164
  params = EnsoGetTokensInput(
167
- chainId=chainId,
165
+ chainId=resolved_chain_id,
168
166
  protocolSlug=protocolSlug,
169
167
  ).model_dump(exclude_none=True)
170
168
 
@@ -177,35 +175,28 @@ class EnsoGetTokens(EnsoBaseTool):
177
175
  response.raise_for_status()
178
176
  json_dict = response.json()
179
177
 
180
- token_decimals = await self.skill_store.get_agent_skill_data(
181
- agent_id,
182
- "enso_get_tokens",
183
- "decimals",
184
- )
178
+ token_decimals = await self.get_agent_skill_data("decimals")
185
179
  if not token_decimals:
186
180
  token_decimals = {}
187
181
 
188
182
  # filter the main tokens from config or the ones that have apy assigned.
189
- res = EnsoGetTokensOutput(res=list[TokenResponseCompact]())
190
- for item in json_dict["data"]:
191
- main_tokens = [item.upper() for item in main_tokens]
192
- if item.get("apy") or (item.get("symbol").upper() in main_tokens):
183
+ res = EnsoGetTokensOutput()
184
+ for item in json_dict.get("data", []):
185
+ symbol = item.get("symbol", "").upper()
186
+ has_apy = bool(item.get("apy"))
187
+ if has_apy or symbol in main_tokens_upper:
193
188
  token_response = TokenResponseCompact(**item)
194
189
  res.res.append(token_response)
195
- token_decimals[token_response.address] = token_response.decimals
196
- if (
197
- token_response.underlyingTokens
198
- and len(token_response.underlyingTokens) > 0
199
- ):
190
+ if token_response.address:
191
+ token_decimals[token_response.address] = (
192
+ token_response.decimals
193
+ )
194
+ if token_response.underlyingTokens:
200
195
  for u_token in token_response.underlyingTokens:
201
- token_decimals[u_token.address] = u_token.decimals
202
-
203
- await self.skill_store.save_agent_skill_data(
204
- agent_id,
205
- "enso_get_tokens",
206
- "decimals",
207
- token_decimals,
208
- )
196
+ if u_token.address:
197
+ token_decimals[u_token.address] = u_token.decimals
198
+
199
+ await self.save_agent_skill_data("decimals", token_decimals)
209
200
 
210
201
  return res
211
202
  except httpx.RequestError as req_err:
@@ -1,26 +1,16 @@
1
- from typing import Literal, Tuple, Type
1
+ from typing import Literal
2
2
 
3
3
  import httpx
4
- from langchain.tools.base import ToolException
4
+ from langchain_core.tools.base import ToolException
5
5
  from pydantic import BaseModel, Field
6
6
 
7
- from .base import EnsoBaseTool, base_url, default_chain_id
7
+ from .base import EnsoBaseTool, base_url
8
8
 
9
9
 
10
10
  class EnsoGetBalancesInput(BaseModel):
11
- """
12
- Input model for retrieving wallet balances.
13
- """
11
+ """Input model for retrieving wallet balances."""
14
12
 
15
- chainId: int = Field(
16
- default_chain_id, description="Chain ID of the blockchain network"
17
- )
18
- # eoaAddress: str = Field(
19
- # description="Address of the eoa with which to associate the ensoWallet for balances"
20
- # )
21
- # useEoa: bool = Field(
22
- # description="If true returns balances for the provided eoaAddress, instead of the associated ensoWallet"
23
- # )
13
+ chainId: int | None = Field(None, description="Chain ID of the blockchain network")
24
14
 
25
15
 
26
16
  class WalletBalance(BaseModel):
@@ -31,9 +21,7 @@ class WalletBalance(BaseModel):
31
21
 
32
22
 
33
23
  class EnsoGetBalancesOutput(BaseModel):
34
- """
35
- Output model for retrieving wallet balances.
36
- """
24
+ """Output model for retrieving wallet balances."""
37
25
 
38
26
  res: list[WalletBalance] | None = Field(
39
27
  None, description="The wallet's balances along with token details."
@@ -41,79 +29,58 @@ class EnsoGetBalancesOutput(BaseModel):
41
29
 
42
30
 
43
31
  class EnsoGetWalletBalances(EnsoBaseTool):
44
- """
45
- This tool allows querying for first 20 token balances of a specific wallet
46
- and blockchain network.
47
-
48
- Attributes:
49
- name (str): Name of the tool, specifically "enso_get_wallet_balances".
50
- description (str): Comprehensive description of the tool's purpose and functionality.
51
- args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
52
- """
32
+ """Retrieve token balances of a wallet on a specified blockchain network."""
53
33
 
54
34
  name: str = "enso_get_wallet_balances"
55
35
  description: str = (
56
36
  "Retrieve token balances of a wallet on a specified blockchain network."
57
37
  )
58
- args_schema: Type[BaseModel] = EnsoGetBalancesInput
38
+ args_schema: type[BaseModel] = EnsoGetBalancesInput
59
39
 
60
40
  async def _arun(
61
41
  self,
62
- chainId: int = default_chain_id,
63
- **kwargs,
42
+ chainId: int | None = None,
43
+ **_: object,
64
44
  ) -> EnsoGetBalancesOutput:
65
- """
66
- Run the tool to get token balances of a wallet.
67
-
68
- Args:
69
- chainId (int): Chain ID of the blockchain network.
70
-
71
- Returns:
72
- EnsoGetBalancesOutput: The list of balances or an error message.
73
- """
74
- url = f"{base_url}/api/v1/wallet/balances"
75
-
76
45
  context = self.get_context()
46
+ resolved_chain_id = self.resolve_chain_id(context, chainId)
77
47
  api_token = self.get_api_token(context)
78
- account = await self.get_account(context)
48
+ wallet_address = await self.get_wallet_address(context)
49
+
79
50
  headers = {
80
51
  "accept": "application/json",
81
52
  "Authorization": f"Bearer {api_token}",
82
53
  }
83
54
 
84
- params = EnsoGetBalancesInput(chainId=chainId).model_dump(exclude_none=True)
85
- params["eoaAddress"] = account.address
55
+ params = EnsoGetBalancesInput(chainId=resolved_chain_id).model_dump(
56
+ exclude_none=True
57
+ )
58
+ params["eoaAddress"] = wallet_address
86
59
  params["useEoa"] = True
87
60
 
88
61
  async with httpx.AsyncClient() as client:
89
62
  try:
90
- # Send the GET request
91
- response = await client.get(url, headers=headers, params=params)
63
+ response = await client.get(
64
+ f"{base_url}/api/v1/wallet/balances",
65
+ headers=headers,
66
+ params=params,
67
+ )
92
68
  response.raise_for_status()
93
-
94
- # Map the response JSON into the WalletBalance model
95
69
  json_dict = response.json()[:20]
96
70
  res = [WalletBalance(**item) for item in json_dict]
97
-
98
- # Return the parsed response
99
71
  return EnsoGetBalancesOutput(res=res)
100
72
  except httpx.RequestError as req_err:
101
73
  raise ToolException("request error from Enso API") from req_err
102
74
  except httpx.HTTPStatusError as http_err:
103
75
  raise ToolException("http error from Enso API") from http_err
104
- except Exception as e:
105
- raise ToolException(f"error from Enso API: {e}") from e
76
+ except Exception as exc: # pragma: no cover - defensive
77
+ raise ToolException(f"error from Enso API: {exc}") from exc
106
78
 
107
79
 
108
80
  class EnsoGetApprovalsInput(BaseModel):
109
- """
110
- Input model for retrieving wallet approvals.
111
- """
81
+ """Input model for retrieving wallet approvals."""
112
82
 
113
- chainId: int = Field(
114
- default_chain_id, description="Chain ID of the blockchain network"
115
- )
116
- fromAddress: str = Field(description="Address of the wallet")
83
+ chainId: int | None = Field(None, description="Chain ID of the blockchain network")
117
84
  routingStrategy: Literal["ensowallet", "router", "delegate"] | None = Field(
118
85
  None, description="Routing strategy to use"
119
86
  )
@@ -126,9 +93,7 @@ class WalletAllowance(BaseModel):
126
93
 
127
94
 
128
95
  class EnsoGetApprovalsOutput(BaseModel):
129
- """
130
- Output model for retrieving wallet approvals.
131
- """
96
+ """Output model for retrieving wallet approvals."""
132
97
 
133
98
  res: list[WalletAllowance] | None = Field(
134
99
  None, description="Response containing the list of token approvals."
@@ -136,42 +101,24 @@ class EnsoGetApprovalsOutput(BaseModel):
136
101
 
137
102
 
138
103
  class EnsoGetWalletApprovals(EnsoBaseTool):
139
- """
140
- This tool allows querying for first 50 token spend approvals associated with a specific wallet
141
- and blockchain network.
142
-
143
- Attributes:
144
- name (str): Name of the tool, specifically "enso_get_wallet_approvals".
145
- description (str): Comprehensive description of the tool's purpose and functionality.
146
- args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
147
- """
104
+ """Retrieve token spend approvals for a wallet on a specified blockchain network."""
148
105
 
149
106
  name: str = "enso_get_wallet_approvals"
150
107
  description: str = (
151
108
  "Retrieve token spend approvals for a wallet on a specified blockchain network."
152
109
  )
153
- args_schema: Type[BaseModel] = EnsoGetApprovalsOutput
110
+ args_schema: type[BaseModel] = EnsoGetApprovalsInput
154
111
 
155
112
  async def _arun(
156
113
  self,
157
- chainId: int = default_chain_id,
158
- **kwargs,
114
+ chainId: int | None = None,
115
+ routingStrategy: Literal["ensowallet", "router", "delegate"] | None = None,
116
+ **_: object,
159
117
  ) -> EnsoGetApprovalsOutput:
160
- """
161
- Run the tool to get token approvals for a wallet.
162
-
163
- Args:
164
- chainId (int): Chain ID of the blockchain network.
165
- **kwargs: optional kwargs for the tool with args schema defined in EnsoGetApprovalsInput.
166
-
167
- Returns:
168
- EnsoGetApprovalsOutput: The list of approvals or an error message.
169
- """
170
- url = f"{base_url}/api/v1/wallet/approvals"
171
-
172
118
  context = self.get_context()
119
+ resolved_chain_id = self.resolve_chain_id(context, chainId)
173
120
  api_token = self.get_api_token(context)
174
- account = await self.get_account(context)
121
+ wallet_address = await self.get_wallet_address(context)
175
122
 
176
123
  headers = {
177
124
  "accept": "application/json",
@@ -179,26 +126,21 @@ class EnsoGetWalletApprovals(EnsoBaseTool):
179
126
  }
180
127
 
181
128
  params = EnsoGetApprovalsInput(
182
- chainId=chainId,
183
- fromAddress=account.address,
184
- )
185
-
186
- if kwargs.get("routingStrategy"):
187
- params.routingStrategy = kwargs["routingStrategy"]
129
+ chainId=resolved_chain_id,
130
+ routingStrategy=routingStrategy,
131
+ ).model_dump(exclude_none=True)
132
+ params["fromAddress"] = wallet_address
188
133
 
189
134
  async with httpx.AsyncClient() as client:
190
135
  try:
191
- # Send the GET request
192
136
  response = await client.get(
193
- url, headers=headers, params=params.model_dump(exclude_none=True)
137
+ f"{base_url}/api/v1/wallet/approvals",
138
+ headers=headers,
139
+ params=params,
194
140
  )
195
141
  response.raise_for_status()
196
-
197
- # Map the response JSON into the ApprovalsResponse model
198
142
  json_dict = response.json()[:50]
199
143
  res = [WalletAllowance(**item) for item in json_dict]
200
-
201
- # Return the parsed response
202
144
  return EnsoGetApprovalsOutput(res=res)
203
145
  except httpx.RequestError as req_err:
204
146
  raise ToolException(
@@ -208,29 +150,23 @@ class EnsoGetWalletApprovals(EnsoBaseTool):
208
150
  raise ToolException(
209
151
  f"http error from Enso API: {http_err}"
210
152
  ) from http_err
211
- except Exception as e:
212
- raise ToolException(f"error from Enso API: {e}") from e
153
+ except Exception as exc: # pragma: no cover - defensive
154
+ raise ToolException(f"error from Enso API: {exc}") from exc
213
155
 
214
156
 
215
157
  class EnsoWalletApproveInput(BaseModel):
216
- """
217
- Input model for approve the wallet.
218
- """
158
+ """Input model for approving token spend for the wallet."""
219
159
 
220
160
  tokenAddress: str = Field(description="ERC20 token address of the token to approve")
221
161
  amount: int = Field(description="Amount of tokens to approve in wei")
222
- chainId: int = Field(
223
- default_chain_id, description="Chain ID of the blockchain network"
224
- )
162
+ chainId: int | None = Field(None, description="Chain ID of the blockchain network")
225
163
  routingStrategy: Literal["ensowallet", "router", "delegate"] | None = Field(
226
164
  None, description="Routing strategy to use"
227
165
  )
228
166
 
229
167
 
230
168
  class EnsoWalletApproveOutput(BaseModel):
231
- """
232
- Output model for approve token for the wallet.
233
- """
169
+ """Output model for approve token for the wallet."""
234
170
 
235
171
  gas: str | None = Field(None, description="The gas estimate for the transaction")
236
172
  token: str | None = Field(None, description="The token address to approve")
@@ -239,133 +175,82 @@ class EnsoWalletApproveOutput(BaseModel):
239
175
 
240
176
 
241
177
  class EnsoWalletApproveArtifact(BaseModel):
242
- """
243
- Output model for approve token for the wallet.
244
- """
178
+ """Artifact returned after broadcasting an approval transaction."""
245
179
 
246
- tx: object | None = Field(None, description="The tx object to use in `ethers`")
180
+ tx: object | None = Field(
181
+ None, description="The transaction object to use in `ethers`"
182
+ )
247
183
  txHash: str | None = Field(None, description="The transaction hash")
248
184
 
249
185
 
250
186
  class EnsoWalletApprove(EnsoBaseTool):
251
- """
252
- This tool is used specifically for broadcasting a ERC20 token spending approval transaction to the network.
253
- It should only be used when the user explicitly requests to broadcast an approval transaction with a specific amount for a certain token.
254
-
255
- **Example Usage:**
256
-
257
- "Broadcast an approval transaction for 10 USDC to the wallet."
258
-
259
- **Important:**
260
- - This tool should be used with extreme caution.
261
- - Approving token spending grants another account permission to spend your tokens.
262
-
263
- Attributes:
264
- name (str): Name of the tool, specifically "enso_wallet_approve".
265
- description (str): Comprehensive description of the tool's purpose and functionality.
266
- args_schema (Type[BaseModel]): Schema for input arguments, specifying expected parameters.
267
- """
187
+ """Broadcast an ERC20 token spending approval transaction."""
268
188
 
269
189
  name: str = "enso_wallet_approve"
270
- description: str = "This tool is used specifically for broadcasting a ERC20 token spending approval transaction to the network. It should only be used when the user explicitly requests to broadcast an approval transaction with a specific amount for a certain token."
271
- args_schema: Type[BaseModel] = EnsoWalletApproveInput
190
+ description: str = (
191
+ "This tool is used specifically for broadcasting a ERC20 token spending approval transaction to the "
192
+ "network. It should only be used when the user explicitly requests to broadcast an approval transaction "
193
+ "with a specific amount for a certain token."
194
+ )
195
+ args_schema: type[BaseModel] = EnsoWalletApproveInput
272
196
  response_format: str = "content_and_artifact"
273
197
 
274
- # def _run(
275
- # self,
276
- # tokenAddress: str,
277
- # amount: int,
278
- # chainId: int = default_chain_id,
279
- # **kwargs,
280
- # ) -> Tuple[EnsoBroadcastWalletApproveOutput, EnsoBroadcastWalletApproveArtifact]:
281
- # """Run the tool to approve enso router for a wallet.
282
-
283
- # Returns:
284
- # Tuple[EnsoBroadcastWalletApproveOutput, EnsoBroadcastWalletApproveArtifact]: A structured output containing the result of token approval.
285
-
286
- # Raises:
287
- # Exception: If there's an error accessing the Enso API.
288
- # """
289
- # raise NotImplementedError("Use _arun instead")
290
-
291
198
  async def _arun(
292
199
  self,
293
200
  tokenAddress: str,
294
201
  amount: int,
295
- chainId: int = default_chain_id,
296
- **kwargs,
297
- ) -> Tuple[EnsoWalletApproveOutput, EnsoWalletApproveArtifact]:
298
- """
299
- Run the tool to approve enso router for a wallet.
300
-
301
- Args:
302
- tokenAddress (str): ERC20 token address of the token to approve.
303
- amount (int): Amount of tokens to approve in wei.
304
- chainId (int): Chain ID of the blockchain network.
305
- **kwargs: optional kwargs for the tool with args schema defined in EnsoGetApproveInput.
306
-
307
- Returns:
308
- Tuple[EnsoBroadcastWalletApproveOutput, EnsoBroadcastWalletApproveArtifact]: The list of approve transaction output or an error message.
309
- """
310
- url = f"{base_url}/api/v1/wallet/approve"
202
+ chainId: int | None = None,
203
+ routingStrategy: Literal["ensowallet", "router", "delegate"] | None = None,
204
+ **_: object,
205
+ ) -> tuple[EnsoWalletApproveOutput, EnsoWalletApproveArtifact]:
311
206
  context = self.get_context()
207
+ resolved_chain_id = self.resolve_chain_id(context, chainId)
312
208
  api_token = self.get_api_token(context)
313
- account = await self.get_account(context)
209
+ wallet_address = await self.get_wallet_address(context)
314
210
 
315
211
  headers = {
316
212
  "accept": "application/json",
317
213
  "Authorization": f"Bearer {api_token}",
318
214
  }
319
215
 
320
- from_address = account.address
321
-
322
216
  params = EnsoWalletApproveInput(
323
217
  tokenAddress=tokenAddress,
324
218
  amount=amount,
325
- chainId=chainId,
326
- )
327
-
328
- if kwargs.get("routingStrategy"):
329
- params.routingStrategy = kwargs["routingStrategy"]
330
-
331
- params = params.model_dump(exclude_none=True)
219
+ chainId=resolved_chain_id,
220
+ routingStrategy=routingStrategy,
221
+ ).model_dump(exclude_none=True)
222
+ params["fromAddress"] = wallet_address
332
223
 
333
- params["fromAddress"] = from_address
334
-
335
- with httpx.Client() as client:
224
+ async with httpx.AsyncClient() as client:
336
225
  try:
337
- # Send the GET request
338
- response = client.get(url, headers=headers, params=params)
226
+ response = await client.get(
227
+ f"{base_url}/api/v1/wallet/approve",
228
+ headers=headers,
229
+ params=params,
230
+ )
339
231
  response.raise_for_status()
340
232
 
341
- # Map the response JSON into the WalletApproveTransaction model
342
233
  json_dict = response.json()
343
234
  content = EnsoWalletApproveOutput(**json_dict)
344
235
  artifact = EnsoWalletApproveArtifact(**json_dict)
345
236
 
346
- # Use the wallet provider to send the transaction
347
237
  wallet_provider = await self.get_wallet_provider(context)
348
-
349
- # Extract transaction data from the Enso API response
350
238
  tx_data = json_dict.get("tx", {})
351
239
  if tx_data:
352
- # Send the transaction using the wallet provider
353
240
  tx_hash = wallet_provider.send_transaction(
354
241
  {
355
242
  "to": tx_data.get("to"),
356
243
  "data": tx_data.get("data", "0x"),
357
244
  "value": tx_data.get("value", 0),
245
+ "from": wallet_address,
358
246
  }
359
247
  )
360
248
 
361
- # Wait for transaction confirmation
362
249
  wallet_provider.wait_for_transaction_receipt(tx_hash)
363
250
  artifact.txHash = tx_hash
364
251
  else:
365
- # For now, return without executing the transaction if no tx data
366
252
  artifact.txHash = "0x0000000000000000000000000000000000000000000000000000000000000000"
367
253
 
368
- # Return the parsed response
369
254
  return (content, artifact)
370
255
  except httpx.RequestError as req_err:
371
256
  raise ToolException(
@@ -375,5 +260,5 @@ class EnsoWalletApprove(EnsoBaseTool):
375
260
  raise ToolException(
376
261
  f"http error from Enso API: {http_err}"
377
262
  ) from http_err
378
- except Exception as e:
379
- raise ToolException(f"error from Enso API: {e}") from e
263
+ except Exception as exc: # pragma: no cover - defensive
264
+ raise ToolException(f"error from Enso API: {exc}") from exc
@@ -0,0 +1,50 @@
1
+ """ERC20 AgentKit skills."""
2
+
3
+ from typing import TypedDict
4
+
5
+ from coinbase_agentkit import erc20_action_provider
6
+
7
+ from intentkit.models.agent import Agent
8
+ from intentkit.skills.base import (
9
+ SkillConfig,
10
+ SkillState,
11
+ action_to_structured_tool,
12
+ get_agentkit_actions,
13
+ )
14
+ from intentkit.skills.erc20.base import ERC20BaseTool
15
+
16
+
17
+ class SkillStates(TypedDict):
18
+ ERC20ActionProvider_get_balance: SkillState
19
+ ERC20ActionProvider_transfer: SkillState
20
+
21
+
22
+ class Config(SkillConfig):
23
+ """Configuration for ERC20 skills."""
24
+
25
+ states: SkillStates
26
+
27
+
28
+ async def get_skills(
29
+ config: Config,
30
+ is_private: bool,
31
+ agent_id: str,
32
+ agent: Agent | None = None,
33
+ **_,
34
+ ) -> list[ERC20BaseTool]:
35
+ """Get all ERC20 skills."""
36
+
37
+ available_skills: list[str] = []
38
+ for skill_name, state in config["states"].items():
39
+ if state == "disabled":
40
+ continue
41
+ if state == "public" or (state == "private" and is_private):
42
+ available_skills.append(skill_name)
43
+
44
+ actions = await get_agentkit_actions(agent_id, [erc20_action_provider], agent=agent)
45
+ tools: list[ERC20BaseTool] = []
46
+ for skill in available_skills:
47
+ for action in actions:
48
+ if action.name.endswith(skill):
49
+ tools.append(action_to_structured_tool(action))
50
+ return tools
@@ -0,0 +1,11 @@
1
+ """ERC20 AgentKit skills base class."""
2
+
3
+ from intentkit.skills.cdp.base import CDPBaseTool
4
+
5
+
6
+ class ERC20BaseTool(CDPBaseTool):
7
+ """Base class for ERC20 tools."""
8
+
9
+ @property
10
+ def category(self) -> str:
11
+ return "erc20"
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
2
+ <rect width="128" height="128" fill="#1e88e5" rx="16" />
3
+ <circle cx="64" cy="64" r="40" fill="#bbdefb" />
4
+ <text x="50%" y="70%" font-family="Arial,Helvetica,sans-serif" font-size="48" fill="#0d47a1" font-weight="700" text-anchor="middle">20</text>
5
+ </svg>