intentkit 0.8.13.dev1__py3-none-any.whl → 0.8.13.dev3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of intentkit might be problematic. Click here for more details.

intentkit/__init__.py CHANGED
@@ -3,7 +3,7 @@
3
3
  A powerful platform for building AI agents with blockchain and cryptocurrency capabilities.
4
4
  """
5
5
 
6
- __version__ = "0.8.13-dev1"
6
+ __version__ = "0.8.13-dev3"
7
7
  __author__ = "hyacinthus"
8
8
  __email__ = "hyacinthus@gmail.com"
9
9
 
@@ -1,4 +1,4 @@
1
- from intentkit.clients.cdp import get_origin_cdp_client, get_wallet_provider
1
+ from intentkit.clients.cdp import get_cdp_client, get_evm_account, get_wallet_provider
2
2
  from intentkit.clients.twitter import (
3
3
  TwitterClient,
4
4
  TwitterClientConfig,
@@ -10,7 +10,8 @@ __all__ = [
10
10
  "TwitterClient",
11
11
  "TwitterClientConfig",
12
12
  "get_twitter_client",
13
- "get_origin_cdp_client",
13
+ "get_evm_account",
14
+ "get_cdp_client",
14
15
  "get_wallet_provider",
15
16
  "get_web3_client",
16
17
  ]
intentkit/clients/cdp.py CHANGED
@@ -4,7 +4,7 @@ import logging
4
4
  from typing import Dict, Optional, Tuple
5
5
 
6
6
  from bip32 import BIP32
7
- from cdp import CdpClient as OriginCdpClient # noqa: E402
7
+ from cdp import CdpClient, EvmServerAccount # noqa: E402
8
8
  from coinbase_agentkit import ( # noqa: E402
9
9
  CdpEvmWalletProvider,
10
10
  CdpEvmWalletProviderConfig,
@@ -19,7 +19,7 @@ from intentkit.models.db import get_session
19
19
  from intentkit.utils.error import IntentKitAPIError # noqa: E402
20
20
 
21
21
  _wallet_providers: Dict[str, Tuple[str, str, CdpEvmWalletProvider]] = {}
22
- _origin_cdp_client: Optional[OriginCdpClient] = None
22
+ _cdp_client: Optional[CdpClient] = None
23
23
 
24
24
  logger = logging.getLogger(__name__)
25
25
 
@@ -59,25 +59,25 @@ def bip39_seed_to_eth_keys(seed_hex: str) -> Dict[str, str]:
59
59
  }
60
60
 
61
61
 
62
- def get_origin_cdp_client() -> OriginCdpClient:
63
- global _origin_cdp_client
64
- if _origin_cdp_client:
65
- return _origin_cdp_client
62
+ def get_cdp_client() -> CdpClient:
63
+ global _cdp_client
64
+ if _cdp_client:
65
+ return _cdp_client
66
66
 
67
67
  # Get credentials from global configuration
68
68
  api_key_id = config.cdp_api_key_id
69
69
  api_key_secret = config.cdp_api_key_secret
70
70
  wallet_secret = config.cdp_wallet_secret
71
71
 
72
- _origin_cdp_client = OriginCdpClient(
72
+ _cdp_client = CdpClient(
73
73
  api_key_id=api_key_id,
74
74
  api_key_secret=api_key_secret,
75
75
  wallet_secret=wallet_secret,
76
76
  )
77
- return _origin_cdp_client
77
+ return _cdp_client
78
78
 
79
79
 
80
- async def get_wallet_provider(agent: Agent) -> CdpEvmWalletProvider:
80
+ def _assert_cdp_wallet_provider(agent: Agent) -> None:
81
81
  if agent.wallet_provider != "cdp":
82
82
  raise IntentKitAPIError(
83
83
  400,
@@ -85,74 +85,93 @@ async def get_wallet_provider(agent: Agent) -> CdpEvmWalletProvider:
85
85
  "Your agent wallet provider is not cdp but you selected a skill that requires a cdp wallet.",
86
86
  )
87
87
 
88
- if not agent.network_id:
89
- raise IntentKitAPIError(
90
- 400,
91
- "BadNetworkID",
92
- "Your agent network ID is not set. Please set it in the agent config.",
93
- )
94
88
 
95
- agent_data = await AgentData.get(agent.id)
89
+ async def _ensure_evm_account(
90
+ agent: Agent, agent_data: AgentData | None = None
91
+ ) -> Tuple[EvmServerAccount, AgentData]:
92
+ cdp_client = get_cdp_client()
93
+ agent_data = agent_data or await AgentData.get(agent.id)
96
94
  address = agent_data.evm_wallet_address
95
+ account: Optional[EvmServerAccount] = None
97
96
 
98
- cache_entry = _wallet_providers.get(agent.id)
99
- if cache_entry:
100
- cached_network_id, cached_address, provider = cache_entry
101
- if cached_network_id == agent.network_id:
102
- if not address:
103
- address = cached_address or provider.get_address()
104
- if cached_address == address:
105
- return provider
106
-
107
- # Get credentials from global config
108
- api_key_id = config.cdp_api_key_id
109
- api_key_secret = config.cdp_api_key_secret
110
- wallet_secret = config.cdp_wallet_secret
111
-
112
- network_id = agent.network_id
113
-
114
- # new agent or address not migrated yet
115
97
  if not address:
116
- cdp_client = get_origin_cdp_client()
117
- # try migrating from v1 cdp_wallet_data
118
98
  if agent_data.cdp_wallet_data:
119
99
  wallet_data = json.loads(agent_data.cdp_wallet_data)
120
100
  if not isinstance(wallet_data, dict):
121
101
  raise ValueError("Invalid wallet data format")
122
102
  if wallet_data.get("default_address_id") and wallet_data.get("seed"):
123
- # verify seed and convert to pk
124
103
  keys = bip39_seed_to_eth_keys(wallet_data["seed"])
125
104
  if keys["address"] != wallet_data["default_address_id"]:
126
105
  raise ValueError(
127
106
  "Bad wallet data, seed does not match default_address_id"
128
107
  )
129
- # try to import wallet to v2
130
108
  logger.info("Migrating wallet data to v2...")
131
- await cdp_client.evm.import_account(
109
+ account = await cdp_client.evm.import_account(
132
110
  name=agent.id,
133
111
  private_key=keys["private_key"],
134
112
  )
135
- address = keys["address"]
113
+ address = account.address
136
114
  logger.info("Migrated wallet data to v2 successfully: %s", address)
137
- # still not address
138
115
  if not address:
139
116
  logger.info("Creating new wallet...")
140
- new_account = await cdp_client.evm.create_account(
117
+ account = await cdp_client.evm.create_account(
141
118
  name=agent.id,
142
119
  )
143
- address = new_account.address
120
+ address = account.address
144
121
  logger.info("Created new wallet: %s", address)
145
122
 
146
123
  agent_data.evm_wallet_address = address
147
124
  await agent_data.save()
148
- # Update agent slug with evm_wallet_address if slug is null or empty
149
125
  if not agent.slug:
150
126
  async with get_session() as db:
151
127
  db_agent = await db.get(AgentTable, agent.id)
152
- if db_agent:
128
+ if db_agent and not db_agent.slug:
153
129
  db_agent.slug = agent_data.evm_wallet_address
154
130
  await db.commit()
155
131
 
132
+ if account is None:
133
+ account = await cdp_client.evm.get_account(address=address)
134
+
135
+ return account, agent_data
136
+
137
+
138
+ async def get_evm_account(agent: Agent) -> EvmServerAccount:
139
+ _assert_cdp_wallet_provider(agent)
140
+ account, _ = await _ensure_evm_account(agent)
141
+ return account
142
+
143
+
144
+ async def get_wallet_provider(agent: Agent) -> CdpEvmWalletProvider:
145
+ _assert_cdp_wallet_provider(agent)
146
+ if not agent.network_id:
147
+ raise IntentKitAPIError(
148
+ 400,
149
+ "BadNetworkID",
150
+ "Your agent network ID is not set. Please set it in the agent config.",
151
+ )
152
+
153
+ agent_data = await AgentData.get(agent.id)
154
+ address = agent_data.evm_wallet_address
155
+
156
+ cache_entry = _wallet_providers.get(agent.id)
157
+ if cache_entry:
158
+ cached_network_id, cached_address, provider = cache_entry
159
+ if cached_network_id == agent.network_id:
160
+ if not address:
161
+ address = cached_address or provider.get_address()
162
+ if cached_address == address:
163
+ return provider
164
+
165
+ account, agent_data = await _ensure_evm_account(agent, agent_data)
166
+ address = account.address
167
+
168
+ # Get credentials from global config
169
+ api_key_id = config.cdp_api_key_id
170
+ api_key_secret = config.cdp_api_key_secret
171
+ wallet_secret = config.cdp_wallet_secret
172
+
173
+ network_id = agent.network_id
174
+
156
175
  wallet_provider_config = CdpEvmWalletProviderConfig(
157
176
  api_key_id=api_key_id,
158
177
  api_key_secret=api_key_secret,
@@ -162,9 +162,10 @@ firecrawl,firecrawl_scrape,firecrawl_scrape,TRUE,3,100,5,,,0x3cdd051eeC909f94965
162
162
  firecrawl,firecrawl_crawl,firecrawl_crawl,TRUE,3,100,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
163
163
  firecrawl,firecrawl_query_indexed_content,firecrawl_query_indexed_content,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
164
164
  firecrawl,firecrawl_clear_indexed_content,firecrawl_clear_indexed_content,TRUE,1,5,5,,,0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0
165
- xmtp,xmtp_transfer,xmtp_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
166
- xmtp,xmtp_swap,xmtp_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
167
- xmtp,xmtp_get_swap_price,xmtp_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
168
- casino,deck_shuffle,casino_deck_shuffle,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
165
+ xmtp,xmtp_transfer,xmtp_transfer,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
166
+ xmtp,xmtp_swap,xmtp_swap,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
167
+ xmtp,xmtp_get_swap_price,xmtp_get_swap_price,TRUE,1,5,5,,,0x445750026A4a1906b61302442E085f9cbAfe206a
168
+ x402,x402_ask_agent,x402_ask_agent,TRUE,1,1,1,,,0x445750026A4a1906b61302442E085f9cbAfe206a
169
+ casino,deck_shuffle,casino_deck_shuffle,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
169
170
  casino,deck_draw,casino_deck_draw,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
170
171
  casino,dice_roll,casino_dice_roll,true,1,5,5,,,0x3cdd051eec909f94965f9c1c657f5b70a172b2c0
intentkit/skills/base.py CHANGED
@@ -26,11 +26,9 @@ from pydantic import (
26
26
  )
27
27
  from pydantic.v1 import ValidationError as ValidationErrorV1
28
28
  from redis.exceptions import RedisError
29
- from web3 import Web3
30
29
 
31
30
  from intentkit.abstracts.graph import AgentContext
32
31
  from intentkit.clients import get_wallet_provider
33
- from intentkit.clients.web3 import get_web3_client
34
32
  from intentkit.models.redis import get_redis
35
33
  from intentkit.models.skill import (
36
34
  AgentSkillData,
@@ -257,14 +255,6 @@ class IntentKitSkill(BaseTool):
257
255
  raise ValueError("No AgentContext found")
258
256
  return runtime.context
259
257
 
260
- def web3_client(self) -> Web3:
261
- """Get a Web3 client for the skill."""
262
- context = self.get_context()
263
- agent = context.agent
264
- network_id = agent.network_id
265
-
266
- return get_web3_client(network_id)
267
-
268
258
  async def get_agent_skill_data(
269
259
  self,
270
260
  key: str,
@@ -0,0 +1,27 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ from web3 import Web3
4
+
5
+ from intentkit.clients import get_evm_account as fetch_evm_account
6
+ from intentkit.clients.web3 import get_web3_client
7
+ from intentkit.skills.base import IntentKitSkill
8
+
9
+ if TYPE_CHECKING:
10
+ from cdp import EvmServerAccount
11
+
12
+
13
+ class IntentKitOnChainSkill(IntentKitSkill):
14
+ """Shared helpers for on-chain enabled skills."""
15
+
16
+ def web3_client(self) -> Web3:
17
+ """Get a Web3 client for the active agent network."""
18
+ context = self.get_context()
19
+ agent = context.agent
20
+ network_id = agent.network_id
21
+ return get_web3_client(network_id)
22
+
23
+ async def get_evm_account(self) -> "EvmServerAccount":
24
+ """Fetch the EVM account associated with the active agent."""
25
+ context = self.get_context()
26
+ agent = context.agent
27
+ return await fetch_evm_account(agent)
@@ -118,6 +118,10 @@ author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
118
118
  author_github = "yornfifty"
119
119
  author_wallet = "0xF60D4B6780D5D51827602D7aC319458bc9e921F4"
120
120
 
121
+ [x402]
122
+ author_github = "hyacinthus"
123
+ author_wallet = "0x445750026A4a1906b61302442E085f9cbAfe206a"
124
+
121
125
  [portfolio]
122
126
  author_github = "bluntbrain"
123
127
  author_wallet = "0x3cdd051eeC909f94965F9c1c657f5b70a172B2C0"
@@ -0,0 +1,53 @@
1
+ """x402 skill category."""
2
+
3
+ import logging
4
+ from typing import TypedDict
5
+
6
+ from intentkit.skills.base import SkillConfig, SkillState
7
+ from intentkit.skills.x402.ask_agent import X402AskAgent
8
+ from intentkit.skills.x402.base import X402BaseSkill
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ _cache: dict[str, X402BaseSkill] = {}
13
+
14
+
15
+ class SkillStates(TypedDict):
16
+ x402_ask_agent: SkillState
17
+
18
+
19
+ class Config(SkillConfig):
20
+ """Configuration for x402 skills."""
21
+
22
+ states: SkillStates
23
+
24
+
25
+ async def get_skills(
26
+ config: "Config",
27
+ is_private: bool,
28
+ **_,
29
+ ) -> list[X402BaseSkill]:
30
+ """Return enabled x402 skills for the agent."""
31
+ enabled_skills = []
32
+ for skill_name, state in config["states"].items():
33
+ if state == "disabled":
34
+ continue
35
+ if state == "public" or (state == "private" and is_private):
36
+ enabled_skills.append(skill_name)
37
+
38
+ result: list[X402BaseSkill] = []
39
+ for name in enabled_skills:
40
+ skill = _get_skill(name)
41
+ if skill:
42
+ result.append(skill)
43
+ return result
44
+
45
+
46
+ def _get_skill(name: str) -> X402BaseSkill | None:
47
+ if name == "x402_ask_agent":
48
+ if name not in _cache:
49
+ _cache[name] = X402AskAgent()
50
+ return _cache[name]
51
+
52
+ logger.warning("Unknown x402 skill requested: %s", name)
53
+ return None
@@ -0,0 +1,141 @@
1
+ import threading
2
+ from typing import Any, Dict, Optional, Type
3
+
4
+ from coinbase_agentkit.wallet_providers.evm_wallet_provider import (
5
+ EvmWalletSigner as CoinbaseEvmWalletSigner,
6
+ )
7
+ from langchain_core.tools import ToolException
8
+ from pydantic import BaseModel, Field
9
+ from x402.clients.httpx import x402HttpxClient
10
+
11
+ from intentkit.clients import get_wallet_provider
12
+ from intentkit.config.config import config
13
+ from intentkit.models.chat import AuthorType
14
+ from intentkit.skills.x402.base import X402BaseSkill
15
+
16
+
17
+ class AskAgentInput(BaseModel):
18
+ """Arguments for the x402 ask agent skill."""
19
+
20
+ agent_id: str = Field(description="ID or slug of the agent to query.")
21
+ message: str = Field(description="Message to send to the target agent.")
22
+ search_mode: Optional[bool] = Field(
23
+ default=None, description="Enable search mode when interacting with the agent."
24
+ )
25
+ super_mode: Optional[bool] = Field(
26
+ default=None, description="Enable super mode when interacting with the agent."
27
+ )
28
+
29
+
30
+ class X402AskAgent(X402BaseSkill):
31
+ """Skill that queries another agent via the x402 API."""
32
+
33
+ name: str = "x402_ask_agent"
34
+ description: str = (
35
+ "Call another agent through the x402 API and return the final agent message."
36
+ )
37
+ args_schema: Type[BaseModel] = AskAgentInput
38
+
39
+ async def _arun(
40
+ self,
41
+ agent_id: str,
42
+ message: str,
43
+ search_mode: Optional[bool] = None,
44
+ super_mode: Optional[bool] = None,
45
+ ) -> str:
46
+ base_url = (config.open_api_base_url or "").rstrip("/")
47
+ if not base_url:
48
+ raise ValueError("X402 API base URL is not configured.")
49
+
50
+ # Use wallet provider signer to satisfy eth_account.BaseAccount interface requirements
51
+ context = self.get_context()
52
+ wallet_provider = await get_wallet_provider(context.agent)
53
+ account = ThreadSafeEvmWalletSigner(wallet_provider)
54
+
55
+ payload: Dict[str, Any] = {
56
+ "agent_id": agent_id,
57
+ "message": message,
58
+ "app_id": "skill",
59
+ }
60
+ if search_mode is not None:
61
+ payload["search_mode"] = search_mode
62
+ if super_mode is not None:
63
+ payload["super_mode"] = super_mode
64
+
65
+ async with x402HttpxClient(
66
+ account=account,
67
+ base_url=base_url,
68
+ timeout=20.0,
69
+ ) as client:
70
+ response = await client.post("/x402", json=payload)
71
+ response.raise_for_status()
72
+ messages = response.json()
73
+ if not isinstance(messages, list) or not messages:
74
+ raise ValueError("Agent returned an empty response.")
75
+
76
+ last_message = messages[-1]
77
+ if not isinstance(last_message, dict):
78
+ raise ValueError("Agent response format is invalid.")
79
+
80
+ author_type = last_message.get("author_type")
81
+ content = last_message.get("message")
82
+
83
+ if author_type == AuthorType.SYSTEM.value:
84
+ raise ToolException(content or "Agent returned a system message.")
85
+
86
+ if not content:
87
+ raise ToolException("Agent response did not include message text.")
88
+
89
+ return str(content)
90
+
91
+
92
+ class ThreadSafeEvmWalletSigner(CoinbaseEvmWalletSigner):
93
+ """EVM wallet signer that avoids nested event loop errors.
94
+
95
+ Coinbase's signer runs async wallet calls in the current thread. When invoked
96
+ inside an active asyncio loop (as happens in async skills), it trips over the
97
+ loop already running. We hop work to a background thread so the provider can
98
+ spin up its own loop safely.
99
+ """
100
+
101
+ def _run_in_thread(self, func: Any, *args: Any, **kwargs: Any) -> Any:
102
+ result: list[Any] = []
103
+ error: list[BaseException] = []
104
+
105
+ def _target() -> None:
106
+ try:
107
+ result.append(func(*args, **kwargs))
108
+ except BaseException as exc: # pragma: no cover - bubble up original error
109
+ error.append(exc)
110
+
111
+ thread = threading.Thread(target=_target, daemon=True)
112
+ thread.start()
113
+ thread.join()
114
+
115
+ if error:
116
+ raise error[0]
117
+ return result[0] if result else None
118
+
119
+ def unsafe_sign_hash(self, message_hash: Any) -> Any:
120
+ return self._run_in_thread(super().unsafe_sign_hash, message_hash)
121
+
122
+ def sign_message(self, signable_message: Any) -> Any:
123
+ return self._run_in_thread(super().sign_message, signable_message)
124
+
125
+ def sign_transaction(self, transaction_dict: Any) -> Any:
126
+ return self._run_in_thread(super().sign_transaction, transaction_dict)
127
+
128
+ def sign_typed_data(
129
+ self,
130
+ domain_data: Optional[Dict[str, Any]] = None,
131
+ message_types: Optional[Dict[str, Any]] = None,
132
+ message_data: Optional[Dict[str, Any]] = None,
133
+ full_message: Optional[Dict[str, Any]] = None,
134
+ ) -> Any:
135
+ return self._run_in_thread(
136
+ super().sign_typed_data,
137
+ domain_data=domain_data,
138
+ message_types=message_types,
139
+ message_data=message_data,
140
+ full_message=full_message,
141
+ )
@@ -0,0 +1,9 @@
1
+ from intentkit.skills.onchain import IntentKitOnChainSkill
2
+
3
+
4
+ class X402BaseSkill(IntentKitOnChainSkill):
5
+ """Base class for x402 skills."""
6
+
7
+ @property
8
+ def category(self) -> str:
9
+ return "x402"
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "x402",
5
+ "description": "Interact with other IntentKit agents through the x402 payment protocol.",
6
+ "x-icon": "https://ai.service.crestal.dev/skills/x402/x402.png",
7
+ "x-tags": [
8
+ "Communication",
9
+ "Infrastructure"
10
+ ],
11
+ "properties": {
12
+ "enabled": {
13
+ "type": "boolean",
14
+ "title": "Enabled",
15
+ "description": "Whether this skill category is enabled.",
16
+ "default": false
17
+ },
18
+ "states": {
19
+ "type": "object",
20
+ "properties": {
21
+ "x402_ask_agent": {
22
+ "type": "string",
23
+ "title": "Ask Agent",
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": "Send a message to another IntentKit agent via the x402 API and return the final agent response.",
35
+ "default": "disabled"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
Binary file
@@ -1,9 +1,9 @@
1
1
  from typing import Dict, Literal
2
2
 
3
- from intentkit.skills.base import IntentKitSkill
3
+ from intentkit.skills.onchain import IntentKitOnChainSkill
4
4
 
5
5
 
6
- class XmtpBaseTool(IntentKitSkill):
6
+ class XmtpBaseTool(IntentKitOnChainSkill):
7
7
  """Base class for XMTP-related skills."""
8
8
 
9
9
  # Set response format to content_and_artifact for returning tuple
@@ -3,7 +3,7 @@ from typing import Literal, Type
3
3
  from langchain_core.tools.base import ToolException
4
4
  from pydantic import BaseModel, Field
5
5
 
6
- from intentkit.clients.cdp import get_origin_cdp_client
6
+ from intentkit.clients.cdp import get_cdp_client
7
7
  from intentkit.skills.xmtp.base import XmtpBaseTool
8
8
 
9
9
 
@@ -50,8 +50,8 @@ class XmtpGetSwapPrice(XmtpBaseTool):
50
50
 
51
51
  network_for_cdp = self.get_cdp_network(agent.network_id)
52
52
 
53
- cdp_client = get_origin_cdp_client()
54
- # Note: Don't use async with context manager as get_origin_cdp_client returns a managed global client
53
+ cdp_client = get_cdp_client()
54
+ # Note: Don't use async with context manager as get_cdp_client returns a managed global client
55
55
  price = await cdp_client.evm.get_swap_price(
56
56
  from_token=from_token,
57
57
  to_token=to_token,
@@ -2,7 +2,7 @@ from typing import List, Tuple, Type
2
2
 
3
3
  from pydantic import BaseModel, Field
4
4
 
5
- from intentkit.clients.cdp import get_origin_cdp_client
5
+ from intentkit.clients.cdp import get_cdp_client
6
6
  from intentkit.models.chat import ChatMessageAttachment, ChatMessageAttachmentType
7
7
  from intentkit.skills.xmtp.base import XmtpBaseTool
8
8
 
@@ -107,15 +107,15 @@ class XmtpSwap(XmtpBaseTool):
107
107
  # https://github.com/coinbase/cdp-sdk/blob/main/examples/python/evm/swaps/create_swap_quote.py
108
108
  network_for_cdp = self.get_cdp_network(agent.network_id)
109
109
 
110
- # Get CDP client from global origin helper (server-side credentials)
111
- cdp_client = get_origin_cdp_client()
110
+ # Get CDP client from the global helper (server-side credentials)
111
+ cdp_client = get_cdp_client()
112
112
 
113
113
  # Call CDP to create swap quote and extract call datas
114
114
  # Be permissive with response shape across SDK versions
115
115
  try:
116
116
  # Attempt the canonical method per CDP SDK examples
117
117
  # create_swap_quote(from_token, to_token, from_amount, network, taker, slippage_bps, signer_address)
118
- # Note: Don't use async with context manager as get_origin_cdp_client returns a managed global client
118
+ # Note: Don't use async with context manager as get_cdp_client returns a managed global client
119
119
  quote = await cdp_client.evm.create_swap_quote(
120
120
  from_token=from_token,
121
121
  to_token=to_token,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intentkit
3
- Version: 0.8.13.dev1
3
+ Version: 0.8.13.dev3
4
4
  Summary: Intent-based AI Agent Platform - Core Package
5
5
  Project-URL: Homepage, https://github.com/crestalnetwork/intentkit
6
6
  Project-URL: Repository, https://github.com/crestalnetwork/intentkit
@@ -1,4 +1,4 @@
1
- intentkit/__init__.py,sha256=IQcA48M2AGddMCj2tAqWrmb2YmKxzSbBMMLcL4oZ-j8,384
1
+ intentkit/__init__.py,sha256=aed72E3E1e647h-JvVmtVM1Jq4PY6LGQuaG_P0_MINo,384
2
2
  intentkit/abstracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  intentkit/abstracts/agent.py,sha256=108gb5W8Q1Sy4G55F2_ZFv2-_CnY76qrBtpIr0Oxxqk,1489
4
4
  intentkit/abstracts/api.py,sha256=ZUc24vaQvQVbbjznx7bV0lbbQxdQPfEV8ZxM2R6wZWo,166
@@ -6,8 +6,8 @@ intentkit/abstracts/engine.py,sha256=C5C9d8vVMePhkKWURKIAbZSDZnmjxj5epL_04E6RpxQ
6
6
  intentkit/abstracts/graph.py,sha256=I3AQMPBuFbMUaANpjl0zLKocg3aXTX9gRkhFJqyvGHc,1285
7
7
  intentkit/abstracts/skill.py,sha256=lRIM0BKuj639Z9MLoFU5eqmHnuCAkbgmeI5E3B3Z_o8,1524
8
8
  intentkit/abstracts/twitter.py,sha256=cEtP7ygR_b-pHdc9i8kBuyooz1cPoGUGwsBHDpowJyY,1262
9
- intentkit/clients/__init__.py,sha256=YmXSif963E5rUfkfHaI6JdWRFU5yNa_yJwafs2KEIVo,406
10
- intentkit/clients/cdp.py,sha256=A-cczpek9iPw6dDxKub_BOjCAtpIbUP_MYYP06fYW90,5791
9
+ intentkit/clients/__init__.py,sha256=wCSVM4whe9xBCL8lrT6r-Zx0-ZTnQI51iQmNlC1HcPQ,432
10
+ intentkit/clients/cdp.py,sha256=sE4ZMX5oK8GIobVGpcofRd6BBkYysqdK07HPkbfUNLQ,6219
11
11
  intentkit/clients/twitter.py,sha256=dMyskssmnxns31RoCr3c2sJTaR3xm8RkI5-8yYz1pGo,19975
12
12
  intentkit/clients/web3.py,sha256=iFjjingL9Aqh3kwUUKN8Tw5N66o2SE_bfo6OhqI-6SU,890
13
13
  intentkit/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -40,11 +40,12 @@ intentkit/models/llm.csv,sha256=0NIGyo-6E9sKkPy-iCw4xl3KK8dFO5t45le1gwfg7Vs,3801
40
40
  intentkit/models/llm.py,sha256=ZnM6qpk9ouTqFysQzzg8TcAfxXASD-H9f1eHsmVjYv8,22186
41
41
  intentkit/models/redis.py,sha256=Vqb9pjeMQ85Az5GvUbqCsQ5stBpFg3n85p94TB40xEw,3727
42
42
  intentkit/models/skill.py,sha256=vGJgKpUmjGsThFznEwMLipuZIlqtto_ovVELp1_AjB8,20709
43
- intentkit/models/skills.csv,sha256=lvQg_1byPvJaHToQbEqRZarfYDuXpP4EXeVJVMc8aDs,19132
43
+ intentkit/models/skills.csv,sha256=4Ni3OlVLLVEv8ipBtFzBJ23pysi59HbJ4CRCMHAMDYQ,19219
44
44
  intentkit/models/user.py,sha256=M79XT1dF1Ju5HKdE49RALeV_XXen7mIvmP9Lhsx9NFw,11485
45
45
  intentkit/skills/__init__.py,sha256=WkjmKB4xvy36zyXMroPMf_DTPgQloNS3L73nVnBmuQI,303
46
- intentkit/skills/base.py,sha256=cZmSEc-wHEGA1hgORYOO6xItVfr0WI7DRdz8hAUHWiI,12602
47
- intentkit/skills/skills.toml,sha256=WQiai9RKIQ2Mqp-eW35_RCn2RW5QLWN3aRgsj7B7OvE,3532
46
+ intentkit/skills/base.py,sha256=WpCrCHJkvg9hi7wbvwMqBdWfPUGQ2NSOHkGziQuoJfc,12297
47
+ intentkit/skills/onchain.py,sha256=U-wggQ-uYpZQAUp1cl7eij6FPvp7kQ84ZxSLZS5fysw,870
48
+ intentkit/skills/skills.toml,sha256=O-s3Y66oswIi9SgwBZY9sva7bUYD3S2nJs9xWUn6SrM,3630
48
49
  intentkit/skills/acolyt/__init__.py,sha256=Q5Fx_9wVX1JkcXNzaf30E0BJB2wHAXReeE8WtDFAvbc,1812
49
50
  intentkit/skills/acolyt/acolyt.jpg,sha256=CwrrouzXzYvnHi1rprYruvZqPopG06ppMczEZmZ7D2s,11559
50
51
  intentkit/skills/acolyt/ask.py,sha256=UuTdjF5961MLDMzDChnD7OGAqi0UYTTFgwGvuAIUDkQ,5871
@@ -435,12 +436,17 @@ intentkit/skills/wow/__init__.py,sha256=m7kbAlh4kQWEixxiEeyVf3v4wUDdzOuFZ79NVsVj
435
436
  intentkit/skills/wow/base.py,sha256=nFt8sJtQQsu2_ZlRasXhyG148fSJYRL-20kEt380PaE,226
436
437
  intentkit/skills/wow/schema.json,sha256=jGpugebVupGTlOUYNu7fN99p-zL-cfaoOYSX7KW8VQc,2292
437
438
  intentkit/skills/wow/wow.svg,sha256=PO0-m6TZjJCql9r1oWohlRV5PyqGc5kIDUEnpP2-5SU,427
439
+ intentkit/skills/x402/__init__.py,sha256=tAO80tBlMluExByWiQ_r2GZlaAYTMsaWxCXDREaqqAg,1315
440
+ intentkit/skills/x402/ask_agent.py,sha256=9zp73uHmYZXnJQtEF7SRxC8N36e41cOwsNqVFo2Q9IQ,5053
441
+ intentkit/skills/x402/base.py,sha256=KhC9CWFEgdfQjWH1QCRJiNSWCnmgypVIe1ap1hb3X5E,211
442
+ intentkit/skills/x402/schema.json,sha256=1mYBzi5t3nSgSBzRv5imAAPG1hEGUWp_-QGJ1vyymoA,1069
443
+ intentkit/skills/x402/x402.png,sha256=0BTtwDFlbdily3dA7ZANZYujEI_2_Ll3_D_091jBDws,68
438
444
  intentkit/skills/xmtp/README.md,sha256=7y3ny77l5WUI758Q3xip1akFEgBdbibkwZjeJDu5MwE,2963
439
445
  intentkit/skills/xmtp/__init__.py,sha256=2x3roc8BaHT_Mfd7IXPw0UgUdca8TDB8NBFvMRibhD0,2180
440
- intentkit/skills/xmtp/base.py,sha256=iZHRzl4KJ1XFRKR_QnR7hYojSyEIB89S8MGoBVarLZY,2495
441
- intentkit/skills/xmtp/price.py,sha256=gwuARYXcAsS5pQVHDqFOCewrHvzHnxVjQxXzDa67fZ8,2871
446
+ intentkit/skills/xmtp/base.py,sha256=hPDcio_mgtD_blsQuMOJcwHQRKiFFaLR022JZZq1HPY,2512
447
+ intentkit/skills/xmtp/price.py,sha256=31M9V-QAmqwNxTimBKtFHti3yYP7e3WGWJg8U31LKYI,2850
442
448
  intentkit/skills/xmtp/schema.json,sha256=DDi_vK1WeoON96j10yTVlRPpjc-8stIG7dwdek2LyXU,2463
443
- intentkit/skills/xmtp/swap.py,sha256=nQ2mqCp_Z2UnIXp81WLZSFOxIm8LSAqTIBDUklTRV3M,8437
449
+ intentkit/skills/xmtp/swap.py,sha256=5OByZPdQEo3XbtR5Fu2t7sVh2Rp8_F_duTOcwCwkbKU,8413
444
450
  intentkit/skills/xmtp/transfer.py,sha256=43t1LG9B_8v5cbGH12F68JDsfd90a9_x2KUsJXnSMbE,7916
445
451
  intentkit/skills/xmtp/xmtp.png,sha256=vQzT-71zIb8aPodg-GkGSQbBnjGAPczWGm3es2ZkJe8,6681
446
452
  intentkit/utils/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
@@ -452,7 +458,7 @@ intentkit/utils/s3.py,sha256=A8Nsx5QJyLsxhj9g7oHNy2-m24tjQUhC9URm8Qb1jFw,10057
452
458
  intentkit/utils/schema.py,sha256=ATeTskEO2Y-MLFcOJEm5BoFJvxqc_zqQwiRS3rO4XDQ,3428
453
459
  intentkit/utils/slack_alert.py,sha256=s7UpRgyzLW7Pbmt8cKzTJgMA9bm4EP-1rQ5KXayHu6E,2264
454
460
  intentkit/utils/tx.py,sha256=2yLLGuhvfBEY5n_GJ8wmIWLCzn0FsYKv5kRNzw_sLUI,1454
455
- intentkit-0.8.13.dev1.dist-info/METADATA,sha256=0flvNmswhgSdNhxO-AfM7A9TEGDvw2Jeh9OnOvJ7YcM,6316
456
- intentkit-0.8.13.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
457
- intentkit-0.8.13.dev1.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
458
- intentkit-0.8.13.dev1.dist-info/RECORD,,
461
+ intentkit-0.8.13.dev3.dist-info/METADATA,sha256=Hi4VzX9QFTnF9lEEPBgeWKxT7W-_u_DHLWjSQx9iDqU,6316
462
+ intentkit-0.8.13.dev3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
463
+ intentkit-0.8.13.dev3.dist-info/licenses/LICENSE,sha256=Bln6DhK-LtcO4aXy-PBcdZv2f24MlJFm_qn222biJtE,1071
464
+ intentkit-0.8.13.dev3.dist-info/RECORD,,