intentkit 0.7.5.dev3__py3-none-any.whl → 0.8.34.dev7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (393) hide show
  1. intentkit/MANIFEST.in +14 -0
  2. intentkit/README.md +88 -0
  3. intentkit/__init__.py +6 -4
  4. intentkit/abstracts/agent.py +4 -5
  5. intentkit/abstracts/engine.py +5 -5
  6. intentkit/abstracts/graph.py +15 -8
  7. intentkit/abstracts/skill.py +6 -144
  8. intentkit/abstracts/twitter.py +4 -5
  9. intentkit/clients/__init__.py +9 -2
  10. intentkit/clients/cdp.py +129 -153
  11. intentkit/{utils → clients}/s3.py +109 -34
  12. intentkit/clients/twitter.py +83 -62
  13. intentkit/clients/web3.py +4 -7
  14. intentkit/config/config.py +123 -90
  15. intentkit/core/account_checking.py +802 -0
  16. intentkit/core/agent.py +313 -498
  17. intentkit/core/asset.py +267 -0
  18. intentkit/core/chat.py +5 -3
  19. intentkit/core/client.py +1 -1
  20. intentkit/core/credit.py +49 -41
  21. intentkit/core/draft.py +201 -0
  22. intentkit/core/draft_chat.py +118 -0
  23. intentkit/core/engine.py +378 -287
  24. intentkit/core/manager/__init__.py +25 -0
  25. intentkit/core/manager/engine.py +220 -0
  26. intentkit/core/manager/service.py +172 -0
  27. intentkit/core/manager/skills.py +178 -0
  28. intentkit/core/middleware.py +231 -0
  29. intentkit/core/prompt.py +74 -114
  30. intentkit/core/scheduler.py +143 -0
  31. intentkit/core/statistics.py +168 -0
  32. intentkit/models/agent.py +931 -518
  33. intentkit/models/agent_data.py +165 -106
  34. intentkit/models/agent_schema.json +38 -251
  35. intentkit/models/app_setting.py +15 -13
  36. intentkit/models/chat.py +86 -140
  37. intentkit/models/credit.py +182 -162
  38. intentkit/models/db.py +42 -23
  39. intentkit/models/db_mig.py +120 -3
  40. intentkit/models/draft.py +222 -0
  41. intentkit/models/llm.csv +31 -0
  42. intentkit/models/llm.py +262 -370
  43. intentkit/models/redis.py +6 -4
  44. intentkit/models/skill.py +222 -101
  45. intentkit/models/skills.csv +173 -0
  46. intentkit/models/team.py +189 -0
  47. intentkit/models/user.py +103 -31
  48. intentkit/skills/acolyt/__init__.py +2 -9
  49. intentkit/skills/acolyt/ask.py +3 -4
  50. intentkit/skills/acolyt/base.py +4 -9
  51. intentkit/skills/acolyt/schema.json +4 -3
  52. intentkit/skills/aixbt/__init__.py +2 -13
  53. intentkit/skills/aixbt/base.py +1 -7
  54. intentkit/skills/aixbt/projects.py +14 -15
  55. intentkit/skills/aixbt/schema.json +4 -4
  56. intentkit/skills/allora/__init__.py +2 -9
  57. intentkit/skills/allora/base.py +4 -9
  58. intentkit/skills/allora/price.py +3 -4
  59. intentkit/skills/allora/schema.json +3 -2
  60. intentkit/skills/base.py +241 -41
  61. intentkit/skills/basename/__init__.py +51 -0
  62. intentkit/skills/basename/base.py +11 -0
  63. intentkit/skills/basename/basename.svg +11 -0
  64. intentkit/skills/basename/schema.json +58 -0
  65. intentkit/skills/carv/__init__.py +115 -121
  66. intentkit/skills/carv/base.py +184 -185
  67. intentkit/skills/carv/fetch_news.py +3 -3
  68. intentkit/skills/carv/onchain_query.py +4 -4
  69. intentkit/skills/carv/schema.json +134 -137
  70. intentkit/skills/carv/token_info_and_price.py +6 -6
  71. intentkit/skills/casino/__init__.py +4 -15
  72. intentkit/skills/casino/base.py +1 -7
  73. intentkit/skills/casino/deck_draw.py +5 -8
  74. intentkit/skills/casino/deck_shuffle.py +6 -6
  75. intentkit/skills/casino/dice_roll.py +2 -4
  76. intentkit/skills/casino/schema.json +0 -1
  77. intentkit/skills/cdp/__init__.py +22 -84
  78. intentkit/skills/cdp/base.py +1 -7
  79. intentkit/skills/cdp/schema.json +11 -314
  80. intentkit/skills/chainlist/__init__.py +2 -7
  81. intentkit/skills/chainlist/base.py +1 -7
  82. intentkit/skills/chainlist/chain_lookup.py +18 -18
  83. intentkit/skills/chainlist/schema.json +3 -5
  84. intentkit/skills/common/__init__.py +2 -9
  85. intentkit/skills/common/base.py +1 -7
  86. intentkit/skills/common/current_time.py +1 -2
  87. intentkit/skills/common/schema.json +2 -2
  88. intentkit/skills/cookiefun/__init__.py +6 -9
  89. intentkit/skills/cookiefun/base.py +2 -7
  90. intentkit/skills/cookiefun/get_account_details.py +7 -7
  91. intentkit/skills/cookiefun/get_account_feed.py +19 -19
  92. intentkit/skills/cookiefun/get_account_smart_followers.py +7 -7
  93. intentkit/skills/cookiefun/get_sectors.py +3 -3
  94. intentkit/skills/cookiefun/schema.json +1 -3
  95. intentkit/skills/cookiefun/search_accounts.py +9 -9
  96. intentkit/skills/cryptocompare/__init__.py +7 -24
  97. intentkit/skills/cryptocompare/api.py +2 -3
  98. intentkit/skills/cryptocompare/base.py +10 -24
  99. intentkit/skills/cryptocompare/fetch_news.py +4 -5
  100. intentkit/skills/cryptocompare/fetch_price.py +6 -7
  101. intentkit/skills/cryptocompare/fetch_top_exchanges.py +4 -5
  102. intentkit/skills/cryptocompare/fetch_top_market_cap.py +4 -5
  103. intentkit/skills/cryptocompare/fetch_top_volume.py +4 -5
  104. intentkit/skills/cryptocompare/fetch_trading_signals.py +5 -6
  105. intentkit/skills/cryptocompare/schema.json +3 -3
  106. intentkit/skills/cryptopanic/__init__.py +7 -10
  107. intentkit/skills/cryptopanic/base.py +51 -55
  108. intentkit/skills/cryptopanic/fetch_crypto_news.py +4 -8
  109. intentkit/skills/cryptopanic/fetch_crypto_sentiment.py +5 -7
  110. intentkit/skills/cryptopanic/schema.json +105 -103
  111. intentkit/skills/dapplooker/__init__.py +2 -9
  112. intentkit/skills/dapplooker/base.py +4 -9
  113. intentkit/skills/dapplooker/dapplooker_token_data.py +7 -7
  114. intentkit/skills/dapplooker/schema.json +3 -5
  115. intentkit/skills/defillama/__init__.py +24 -74
  116. intentkit/skills/defillama/api.py +6 -9
  117. intentkit/skills/defillama/base.py +8 -19
  118. intentkit/skills/defillama/coins/fetch_batch_historical_prices.py +8 -10
  119. intentkit/skills/defillama/coins/fetch_block.py +6 -8
  120. intentkit/skills/defillama/coins/fetch_current_prices.py +8 -10
  121. intentkit/skills/defillama/coins/fetch_first_price.py +7 -9
  122. intentkit/skills/defillama/coins/fetch_historical_prices.py +9 -11
  123. intentkit/skills/defillama/coins/fetch_price_chart.py +9 -11
  124. intentkit/skills/defillama/coins/fetch_price_percentage.py +7 -9
  125. intentkit/skills/defillama/config/chains.py +1 -3
  126. intentkit/skills/defillama/fees/fetch_fees_overview.py +24 -26
  127. intentkit/skills/defillama/schema.json +5 -1
  128. intentkit/skills/defillama/stablecoins/fetch_stablecoin_chains.py +16 -18
  129. intentkit/skills/defillama/stablecoins/fetch_stablecoin_charts.py +8 -10
  130. intentkit/skills/defillama/stablecoins/fetch_stablecoin_prices.py +5 -7
  131. intentkit/skills/defillama/stablecoins/fetch_stablecoins.py +7 -9
  132. intentkit/skills/defillama/tests/api_integration.test.py +1 -1
  133. intentkit/skills/defillama/tvl/fetch_chain_historical_tvl.py +4 -6
  134. intentkit/skills/defillama/tvl/fetch_chains.py +9 -11
  135. intentkit/skills/defillama/tvl/fetch_historical_tvl.py +4 -6
  136. intentkit/skills/defillama/tvl/fetch_protocol.py +32 -38
  137. intentkit/skills/defillama/tvl/fetch_protocol_current_tvl.py +3 -5
  138. intentkit/skills/defillama/tvl/fetch_protocols.py +37 -45
  139. intentkit/skills/defillama/volumes/fetch_dex_overview.py +42 -48
  140. intentkit/skills/defillama/volumes/fetch_dex_summary.py +35 -37
  141. intentkit/skills/defillama/volumes/fetch_options_overview.py +24 -28
  142. intentkit/skills/defillama/yields/fetch_pool_chart.py +10 -12
  143. intentkit/skills/defillama/yields/fetch_pools.py +26 -30
  144. intentkit/skills/dexscreener/__init__.py +97 -102
  145. intentkit/skills/dexscreener/base.py +125 -130
  146. intentkit/skills/dexscreener/get_pair_info.py +4 -5
  147. intentkit/skills/dexscreener/get_token_pairs.py +4 -5
  148. intentkit/skills/dexscreener/get_tokens_info.py +7 -8
  149. intentkit/skills/dexscreener/model/search_token_response.py +80 -82
  150. intentkit/skills/dexscreener/schema.json +91 -93
  151. intentkit/skills/dexscreener/search_token.py +182 -184
  152. intentkit/skills/dexscreener/utils.py +15 -14
  153. intentkit/skills/dune_analytics/__init__.py +7 -9
  154. intentkit/skills/dune_analytics/base.py +48 -52
  155. intentkit/skills/dune_analytics/fetch_kol_buys.py +5 -7
  156. intentkit/skills/dune_analytics/fetch_nation_metrics.py +6 -8
  157. intentkit/skills/dune_analytics/schema.json +104 -99
  158. intentkit/skills/elfa/__init__.py +5 -18
  159. intentkit/skills/elfa/base.py +10 -14
  160. intentkit/skills/elfa/mention.py +19 -21
  161. intentkit/skills/elfa/schema.json +3 -2
  162. intentkit/skills/elfa/stats.py +4 -4
  163. intentkit/skills/elfa/tokens.py +12 -12
  164. intentkit/skills/elfa/utils.py +26 -28
  165. intentkit/skills/enso/__init__.py +11 -31
  166. intentkit/skills/enso/base.py +54 -35
  167. intentkit/skills/enso/best_yield.py +16 -24
  168. intentkit/skills/enso/networks.py +6 -11
  169. intentkit/skills/enso/prices.py +11 -13
  170. intentkit/skills/enso/route.py +34 -38
  171. intentkit/skills/enso/schema.json +3 -2
  172. intentkit/skills/enso/tokens.py +29 -38
  173. intentkit/skills/enso/wallet.py +76 -191
  174. intentkit/skills/erc20/__init__.py +50 -0
  175. intentkit/skills/erc20/base.py +11 -0
  176. intentkit/skills/erc20/erc20.svg +5 -0
  177. intentkit/skills/erc20/schema.json +74 -0
  178. intentkit/skills/erc721/__init__.py +53 -0
  179. intentkit/skills/erc721/base.py +11 -0
  180. intentkit/skills/erc721/erc721.svg +5 -0
  181. intentkit/skills/erc721/schema.json +90 -0
  182. intentkit/skills/firecrawl/__init__.py +5 -18
  183. intentkit/skills/firecrawl/base.py +4 -9
  184. intentkit/skills/firecrawl/clear.py +4 -8
  185. intentkit/skills/firecrawl/crawl.py +19 -19
  186. intentkit/skills/firecrawl/query.py +4 -3
  187. intentkit/skills/firecrawl/schema.json +2 -6
  188. intentkit/skills/firecrawl/scrape.py +17 -22
  189. intentkit/skills/firecrawl/utils.py +50 -42
  190. intentkit/skills/github/__init__.py +2 -7
  191. intentkit/skills/github/base.py +1 -7
  192. intentkit/skills/github/github_search.py +1 -2
  193. intentkit/skills/github/schema.json +3 -4
  194. intentkit/skills/heurist/__init__.py +8 -27
  195. intentkit/skills/heurist/base.py +4 -9
  196. intentkit/skills/heurist/image_generation_animagine_xl.py +13 -15
  197. intentkit/skills/heurist/image_generation_arthemy_comics.py +13 -15
  198. intentkit/skills/heurist/image_generation_arthemy_real.py +13 -15
  199. intentkit/skills/heurist/image_generation_braindance.py +13 -15
  200. intentkit/skills/heurist/image_generation_cyber_realistic_xl.py +13 -15
  201. intentkit/skills/heurist/image_generation_flux_1_dev.py +13 -15
  202. intentkit/skills/heurist/image_generation_sdxl.py +13 -15
  203. intentkit/skills/heurist/schema.json +2 -2
  204. intentkit/skills/http/__init__.py +4 -15
  205. intentkit/skills/http/base.py +1 -7
  206. intentkit/skills/http/get.py +21 -16
  207. intentkit/skills/http/post.py +23 -18
  208. intentkit/skills/http/put.py +23 -18
  209. intentkit/skills/http/schema.json +4 -5
  210. intentkit/skills/lifi/__init__.py +8 -13
  211. intentkit/skills/lifi/base.py +3 -9
  212. intentkit/skills/lifi/schema.json +17 -8
  213. intentkit/skills/lifi/token_execute.py +150 -60
  214. intentkit/skills/lifi/token_quote.py +8 -10
  215. intentkit/skills/lifi/utils.py +104 -51
  216. intentkit/skills/moralis/__init__.py +6 -10
  217. intentkit/skills/moralis/api.py +6 -7
  218. intentkit/skills/moralis/base.py +5 -10
  219. intentkit/skills/moralis/fetch_chain_portfolio.py +10 -11
  220. intentkit/skills/moralis/fetch_nft_portfolio.py +22 -22
  221. intentkit/skills/moralis/fetch_solana_portfolio.py +11 -12
  222. intentkit/skills/moralis/fetch_wallet_portfolio.py +8 -9
  223. intentkit/skills/moralis/schema.json +7 -2
  224. intentkit/skills/morpho/__init__.py +52 -0
  225. intentkit/skills/morpho/base.py +11 -0
  226. intentkit/skills/morpho/morpho.svg +12 -0
  227. intentkit/skills/morpho/schema.json +73 -0
  228. intentkit/skills/nation/__init__.py +4 -9
  229. intentkit/skills/nation/base.py +5 -10
  230. intentkit/skills/nation/nft_check.py +3 -4
  231. intentkit/skills/nation/schema.json +4 -3
  232. intentkit/skills/onchain.py +30 -0
  233. intentkit/skills/openai/__init__.py +17 -18
  234. intentkit/skills/openai/base.py +10 -14
  235. intentkit/skills/openai/dalle_image_generation.py +4 -9
  236. intentkit/skills/openai/gpt_avatar_generator.py +102 -0
  237. intentkit/skills/openai/gpt_image_generation.py +5 -9
  238. intentkit/skills/openai/gpt_image_mini_generator.py +92 -0
  239. intentkit/skills/openai/gpt_image_to_image.py +5 -9
  240. intentkit/skills/openai/image_to_text.py +3 -7
  241. intentkit/skills/openai/schema.json +34 -3
  242. intentkit/skills/portfolio/__init__.py +11 -35
  243. intentkit/skills/portfolio/base.py +33 -19
  244. intentkit/skills/portfolio/schema.json +3 -5
  245. intentkit/skills/portfolio/token_balances.py +21 -21
  246. intentkit/skills/portfolio/wallet_approvals.py +17 -18
  247. intentkit/skills/portfolio/wallet_defi_positions.py +3 -3
  248. intentkit/skills/portfolio/wallet_history.py +31 -31
  249. intentkit/skills/portfolio/wallet_net_worth.py +13 -13
  250. intentkit/skills/portfolio/wallet_nfts.py +19 -19
  251. intentkit/skills/portfolio/wallet_profitability.py +18 -18
  252. intentkit/skills/portfolio/wallet_profitability_summary.py +5 -5
  253. intentkit/skills/portfolio/wallet_stats.py +3 -3
  254. intentkit/skills/portfolio/wallet_swaps.py +19 -19
  255. intentkit/skills/pyth/__init__.py +50 -0
  256. intentkit/skills/pyth/base.py +11 -0
  257. intentkit/skills/pyth/pyth.svg +6 -0
  258. intentkit/skills/pyth/schema.json +75 -0
  259. intentkit/skills/skills.toml +36 -0
  260. intentkit/skills/slack/__init__.py +5 -17
  261. intentkit/skills/slack/base.py +3 -9
  262. intentkit/skills/slack/get_channel.py +8 -8
  263. intentkit/skills/slack/get_message.py +9 -9
  264. intentkit/skills/slack/schedule_message.py +5 -5
  265. intentkit/skills/slack/schema.json +2 -2
  266. intentkit/skills/slack/send_message.py +3 -5
  267. intentkit/skills/supabase/__init__.py +7 -23
  268. intentkit/skills/supabase/base.py +1 -7
  269. intentkit/skills/supabase/delete_data.py +4 -4
  270. intentkit/skills/supabase/fetch_data.py +12 -12
  271. intentkit/skills/supabase/insert_data.py +4 -4
  272. intentkit/skills/supabase/invoke_function.py +6 -6
  273. intentkit/skills/supabase/schema.json +2 -3
  274. intentkit/skills/supabase/update_data.py +6 -6
  275. intentkit/skills/supabase/upsert_data.py +4 -4
  276. intentkit/skills/superfluid/__init__.py +53 -0
  277. intentkit/skills/superfluid/base.py +11 -0
  278. intentkit/skills/superfluid/schema.json +89 -0
  279. intentkit/skills/superfluid/superfluid.svg +6 -0
  280. intentkit/skills/system/__init__.py +7 -24
  281. intentkit/skills/system/add_autonomous_task.py +10 -12
  282. intentkit/skills/system/delete_autonomous_task.py +2 -2
  283. intentkit/skills/system/edit_autonomous_task.py +14 -18
  284. intentkit/skills/system/list_autonomous_tasks.py +3 -5
  285. intentkit/skills/system/read_agent_api_key.py +6 -4
  286. intentkit/skills/system/regenerate_agent_api_key.py +6 -4
  287. intentkit/skills/system/schema.json +6 -8
  288. intentkit/skills/tavily/__init__.py +3 -12
  289. intentkit/skills/tavily/base.py +4 -9
  290. intentkit/skills/tavily/schema.json +3 -5
  291. intentkit/skills/tavily/tavily_extract.py +2 -4
  292. intentkit/skills/tavily/tavily_search.py +4 -6
  293. intentkit/skills/token/__init__.py +5 -10
  294. intentkit/skills/token/base.py +7 -11
  295. intentkit/skills/token/erc20_transfers.py +19 -19
  296. intentkit/skills/token/schema.json +3 -6
  297. intentkit/skills/token/token_analytics.py +3 -3
  298. intentkit/skills/token/token_price.py +13 -13
  299. intentkit/skills/token/token_search.py +9 -9
  300. intentkit/skills/twitter/__init__.py +11 -35
  301. intentkit/skills/twitter/base.py +22 -34
  302. intentkit/skills/twitter/follow_user.py +2 -6
  303. intentkit/skills/twitter/get_mentions.py +5 -12
  304. intentkit/skills/twitter/get_timeline.py +4 -12
  305. intentkit/skills/twitter/get_user_by_username.py +2 -6
  306. intentkit/skills/twitter/get_user_tweets.py +5 -13
  307. intentkit/skills/twitter/like_tweet.py +2 -6
  308. intentkit/skills/twitter/post_tweet.py +6 -9
  309. intentkit/skills/twitter/reply_tweet.py +6 -9
  310. intentkit/skills/twitter/retweet.py +2 -6
  311. intentkit/skills/twitter/schema.json +1 -0
  312. intentkit/skills/twitter/search_tweets.py +4 -12
  313. intentkit/skills/unrealspeech/__init__.py +2 -7
  314. intentkit/skills/unrealspeech/base.py +2 -8
  315. intentkit/skills/unrealspeech/schema.json +2 -5
  316. intentkit/skills/unrealspeech/text_to_speech.py +8 -8
  317. intentkit/skills/venice_audio/__init__.py +98 -106
  318. intentkit/skills/venice_audio/base.py +117 -121
  319. intentkit/skills/venice_audio/input.py +41 -41
  320. intentkit/skills/venice_audio/schema.json +151 -152
  321. intentkit/skills/venice_audio/venice_audio.py +38 -21
  322. intentkit/skills/venice_image/__init__.py +147 -154
  323. intentkit/skills/venice_image/api.py +138 -138
  324. intentkit/skills/venice_image/base.py +185 -192
  325. intentkit/skills/venice_image/config.py +33 -35
  326. intentkit/skills/venice_image/image_enhance/image_enhance.py +2 -3
  327. intentkit/skills/venice_image/image_enhance/image_enhance_base.py +21 -23
  328. intentkit/skills/venice_image/image_enhance/image_enhance_input.py +38 -40
  329. intentkit/skills/venice_image/image_generation/image_generation_base.py +11 -10
  330. intentkit/skills/venice_image/image_generation/image_generation_fluently_xl.py +26 -26
  331. intentkit/skills/venice_image/image_generation/image_generation_flux_dev.py +27 -27
  332. intentkit/skills/venice_image/image_generation/image_generation_flux_dev_uncensored.py +26 -26
  333. intentkit/skills/venice_image/image_generation/image_generation_input.py +158 -158
  334. intentkit/skills/venice_image/image_generation/image_generation_lustify_sdxl.py +26 -26
  335. intentkit/skills/venice_image/image_generation/image_generation_pony_realism.py +26 -26
  336. intentkit/skills/venice_image/image_generation/image_generation_stable_diffusion_3_5.py +28 -28
  337. intentkit/skills/venice_image/image_generation/image_generation_venice_sd35.py +28 -28
  338. intentkit/skills/venice_image/image_upscale/image_upscale.py +3 -3
  339. intentkit/skills/venice_image/image_upscale/image_upscale_base.py +21 -23
  340. intentkit/skills/venice_image/image_upscale/image_upscale_input.py +22 -22
  341. intentkit/skills/venice_image/image_vision/image_vision.py +2 -2
  342. intentkit/skills/venice_image/image_vision/image_vision_base.py +17 -17
  343. intentkit/skills/venice_image/image_vision/image_vision_input.py +9 -9
  344. intentkit/skills/venice_image/schema.json +267 -267
  345. intentkit/skills/venice_image/utils.py +77 -78
  346. intentkit/skills/web_scraper/__init__.py +5 -18
  347. intentkit/skills/web_scraper/base.py +21 -7
  348. intentkit/skills/web_scraper/document_indexer.py +7 -6
  349. intentkit/skills/web_scraper/schema.json +2 -6
  350. intentkit/skills/web_scraper/scrape_and_index.py +15 -15
  351. intentkit/skills/web_scraper/utils.py +62 -63
  352. intentkit/skills/web_scraper/website_indexer.py +17 -19
  353. intentkit/skills/weth/__init__.py +49 -0
  354. intentkit/skills/weth/base.py +11 -0
  355. intentkit/skills/weth/schema.json +58 -0
  356. intentkit/skills/weth/weth.svg +6 -0
  357. intentkit/skills/wow/__init__.py +51 -0
  358. intentkit/skills/wow/base.py +11 -0
  359. intentkit/skills/wow/schema.json +89 -0
  360. intentkit/skills/wow/wow.svg +7 -0
  361. intentkit/skills/x402/__init__.py +58 -0
  362. intentkit/skills/x402/base.py +99 -0
  363. intentkit/skills/x402/http_request.py +117 -0
  364. intentkit/skills/x402/schema.json +40 -0
  365. intentkit/skills/x402/x402.webp +0 -0
  366. intentkit/skills/xmtp/__init__.py +4 -15
  367. intentkit/skills/xmtp/base.py +5 -5
  368. intentkit/skills/xmtp/price.py +7 -6
  369. intentkit/skills/xmtp/schema.json +69 -71
  370. intentkit/skills/xmtp/swap.py +6 -8
  371. intentkit/skills/xmtp/transfer.py +4 -6
  372. intentkit/utils/__init__.py +4 -0
  373. intentkit/utils/chain.py +198 -96
  374. intentkit/utils/ens.py +135 -0
  375. intentkit/utils/error.py +5 -2
  376. intentkit/utils/logging.py +9 -11
  377. intentkit/utils/schema.py +100 -0
  378. intentkit/utils/slack_alert.py +8 -8
  379. intentkit/utils/tx.py +16 -8
  380. intentkit/uv.lock +3377 -0
  381. {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/METADATA +13 -15
  382. intentkit-0.8.34.dev7.dist-info/RECORD +478 -0
  383. intentkit-0.8.34.dev7.dist-info/licenses/LICENSE +21 -0
  384. intentkit/core/node.py +0 -215
  385. intentkit/models/conversation.py +0 -286
  386. intentkit/models/generator.py +0 -347
  387. intentkit/skills/cdp/get_balance.py +0 -110
  388. intentkit/skills/cdp/swap.py +0 -121
  389. intentkit/skills/moralis/tests/__init__.py +0 -0
  390. intentkit/skills/moralis/tests/test_wallet.py +0 -511
  391. intentkit-0.7.5.dev3.dist-info/RECORD +0 -424
  392. {intentkit-0.7.5.dev3.dist-info/licenses → intentkit}/LICENSE +0 -0
  393. {intentkit-0.7.5.dev3.dist-info → intentkit-0.8.34.dev7.dist-info}/WHEEL +0 -0
@@ -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>
@@ -0,0 +1,74 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "ERC20",
5
+ "description": "ERC20 token balance and transfer actions via Coinbase AgentKit",
6
+ "x-icon": "https://ai.service.crestal.dev/skills/erc20/erc20.svg",
7
+ "x-tags": [
8
+ "Crypto",
9
+ "DeFi"
10
+ ],
11
+ "properties": {
12
+ "enabled": {
13
+ "type": "boolean",
14
+ "title": "Enabled",
15
+ "description": "Whether this skill is enabled",
16
+ "default": false
17
+ },
18
+ "states": {
19
+ "type": "object",
20
+ "properties": {
21
+ "ERC20ActionProvider_get_balance": {
22
+ "type": "string",
23
+ "title": "Get ERC20 Balance",
24
+ "enum": [
25
+ "disabled",
26
+ "public",
27
+ "private"
28
+ ],
29
+ "x-enum-title": [
30
+ "Disabled",
31
+ "Agent Owner + All Users",
32
+ "Agent Owner Only"
33
+ ],
34
+ "description": "State for ERC20ActionProvider_get_balance",
35
+ "default": "disabled"
36
+ },
37
+ "ERC20ActionProvider_transfer": {
38
+ "type": "string",
39
+ "title": "Transfer ERC20",
40
+ "enum": [
41
+ "disabled",
42
+ "public",
43
+ "private"
44
+ ],
45
+ "x-enum-title": [
46
+ "Disabled",
47
+ "Agent Owner + All Users",
48
+ "Agent Owner Only"
49
+ ],
50
+ "description": "State for ERC20ActionProvider_transfer",
51
+ "default": "disabled"
52
+ }
53
+ },
54
+ "description": "States for each ERC20 skill (disabled, public, or private)"
55
+ },
56
+ "api_key_provider": {
57
+ "type": "string",
58
+ "title": "API Key Provider",
59
+ "description": "Who provides the API key",
60
+ "enum": [
61
+ "platform"
62
+ ],
63
+ "x-enum-title": [
64
+ "Nation Hosted"
65
+ ],
66
+ "default": "platform"
67
+ }
68
+ },
69
+ "required": [
70
+ "states",
71
+ "enabled"
72
+ ],
73
+ "additionalProperties": true
74
+ }
@@ -0,0 +1,53 @@
1
+ """ERC721 AgentKit skills."""
2
+
3
+ from typing import TypedDict
4
+
5
+ from coinbase_agentkit import erc721_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.erc721.base import ERC721BaseTool
15
+
16
+
17
+ class SkillStates(TypedDict):
18
+ Erc721ActionProvider_get_balance: SkillState
19
+ Erc721ActionProvider_mint: SkillState
20
+ Erc721ActionProvider_transfer: SkillState
21
+
22
+
23
+ class Config(SkillConfig):
24
+ """Configuration for ERC721 skills."""
25
+
26
+ states: SkillStates
27
+
28
+
29
+ async def get_skills(
30
+ config: Config,
31
+ is_private: bool,
32
+ agent_id: str,
33
+ agent: Agent | None = None,
34
+ **_,
35
+ ) -> list[ERC721BaseTool]:
36
+ """Get all ERC721 skills."""
37
+
38
+ available_skills: list[str] = []
39
+ for skill_name, state in config["states"].items():
40
+ if state == "disabled":
41
+ continue
42
+ if state == "public" or (state == "private" and is_private):
43
+ available_skills.append(skill_name)
44
+
45
+ actions = await get_agentkit_actions(
46
+ agent_id, [erc721_action_provider], agent=agent
47
+ )
48
+ tools: list[ERC721BaseTool] = []
49
+ for skill in available_skills:
50
+ for action in actions:
51
+ if action.name.endswith(skill):
52
+ tools.append(action_to_structured_tool(action))
53
+ return tools
@@ -0,0 +1,11 @@
1
+ """ERC721 AgentKit skills base class."""
2
+
3
+ from intentkit.skills.cdp.base import CDPBaseTool
4
+
5
+
6
+ class ERC721BaseTool(CDPBaseTool):
7
+ """Base class for ERC721 tools."""
8
+
9
+ @property
10
+ def category(self) -> str:
11
+ return "erc721"
@@ -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="#6a1b9a" rx="16" />
3
+ <polygon points="64,24 100,64 64,104 28,64" fill="#ce93d8" />
4
+ <text x="50%" y="72%" font-family="Arial,Helvetica,sans-serif" font-size="40" fill="#4a148c" font-weight="700" text-anchor="middle">721</text>
5
+ </svg>