intentkit 0.7.5.dev17__py3-none-any.whl → 0.7.5.dev18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of intentkit might be problematic. Click here for more details.
- intentkit/__init__.py +1 -1
- intentkit/config/config.py +0 -5
- intentkit/core/engine.py +61 -42
- intentkit/models/llm.py +8 -8
- intentkit/skills/enso/__init__.py +1 -1
- intentkit/skills/enso/base.py +44 -17
- intentkit/skills/enso/best_yield.py +11 -17
- intentkit/skills/enso/networks.py +3 -2
- intentkit/skills/enso/prices.py +9 -9
- intentkit/skills/enso/route.py +27 -23
- intentkit/skills/enso/tokens.py +24 -21
- intentkit/skills/enso/wallet.py +71 -186
- {intentkit-0.7.5.dev17.dist-info → intentkit-0.7.5.dev18.dist-info}/METADATA +1 -1
- {intentkit-0.7.5.dev17.dist-info → intentkit-0.7.5.dev18.dist-info}/RECORD +16 -16
- {intentkit-0.7.5.dev17.dist-info → intentkit-0.7.5.dev18.dist-info}/WHEEL +0 -0
- {intentkit-0.7.5.dev17.dist-info → intentkit-0.7.5.dev18.dist-info}/licenses/LICENSE +0 -0
intentkit/skills/enso/route.py
CHANGED
|
@@ -6,7 +6,7 @@ from pydantic import BaseModel, Field
|
|
|
6
6
|
|
|
7
7
|
from intentkit.skills.enso.networks import EnsoGetNetworks
|
|
8
8
|
|
|
9
|
-
from .base import EnsoBaseTool, base_url,
|
|
9
|
+
from .base import EnsoBaseTool, base_url, format_amount_with_decimals
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class EnsoRouteShortcutInput(BaseModel):
|
|
@@ -18,9 +18,9 @@ class EnsoRouteShortcutInput(BaseModel):
|
|
|
18
18
|
False,
|
|
19
19
|
description="Whether to broadcast the transaction or not, this is false by default.",
|
|
20
20
|
)
|
|
21
|
-
chainId: int = Field(
|
|
22
|
-
|
|
23
|
-
description="(Optional) Chain ID of the network to execute the transaction on.
|
|
21
|
+
chainId: int | None = Field(
|
|
22
|
+
None,
|
|
23
|
+
description="(Optional) Chain ID of the network to execute the transaction on. Defaults to the agent's configured network.",
|
|
24
24
|
)
|
|
25
25
|
amountIn: list[int] = Field(
|
|
26
26
|
description="Amount of tokenIn to swap in wei, you should multiply user's requested value by token decimals."
|
|
@@ -162,7 +162,7 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
162
162
|
amountIn: list[int],
|
|
163
163
|
tokenIn: list[str],
|
|
164
164
|
tokenOut: list[str],
|
|
165
|
-
chainId: int =
|
|
165
|
+
chainId: int | None = None,
|
|
166
166
|
broadcast_requested: bool = False,
|
|
167
167
|
**kwargs,
|
|
168
168
|
) -> EnsoRouteShortcutOutput:
|
|
@@ -173,7 +173,7 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
173
173
|
amountIn (list[int]): Amount of tokenIn to swap in wei, you should multiply user's requested value by token decimals.
|
|
174
174
|
tokenIn (list[str]): Ethereum address of the token to swap or enter into a position from (For ETH, use 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee).
|
|
175
175
|
tokenOut (list[str]): Ethereum address of the token to swap or enter into a position to (For ETH, use 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee).
|
|
176
|
-
chainId (int): The chain id of the network to be used for swap, deposit and routing.
|
|
176
|
+
chainId (int | None): The chain id of the network to be used for swap, deposit and routing. Defaults to the agent's configured network.
|
|
177
177
|
broadcast_requested (bool): User should ask for broadcasting the transaction explicitly, otherwise it is always false.
|
|
178
178
|
|
|
179
179
|
Returns:
|
|
@@ -182,8 +182,9 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
182
182
|
|
|
183
183
|
context = self.get_context()
|
|
184
184
|
agent_id = context.agent_id
|
|
185
|
+
resolved_chain_id = self.resolve_chain_id(context, chainId)
|
|
185
186
|
api_token = self.get_api_token(context)
|
|
186
|
-
|
|
187
|
+
wallet_address = await self.get_wallet_address(context)
|
|
187
188
|
|
|
188
189
|
async with httpx.AsyncClient() as client:
|
|
189
190
|
try:
|
|
@@ -193,9 +194,10 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
193
194
|
)
|
|
194
195
|
|
|
195
196
|
if networks:
|
|
197
|
+
resolved_key = str(resolved_chain_id)
|
|
196
198
|
network_name = (
|
|
197
|
-
networks.get(
|
|
198
|
-
if networks.get(
|
|
199
|
+
networks.get(resolved_key).get("name")
|
|
200
|
+
if networks.get(resolved_key)
|
|
199
201
|
else None
|
|
200
202
|
)
|
|
201
203
|
if network_name is None:
|
|
@@ -204,12 +206,12 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
204
206
|
).arun()
|
|
205
207
|
|
|
206
208
|
for network in networks.res:
|
|
207
|
-
if network.id ==
|
|
209
|
+
if network.id == resolved_chain_id:
|
|
208
210
|
network_name = network.name
|
|
209
211
|
|
|
210
212
|
if not network_name:
|
|
211
213
|
raise ToolException(
|
|
212
|
-
f"network name not found for chainId: {
|
|
214
|
+
f"network name not found for chainId: {resolved_chain_id}"
|
|
213
215
|
)
|
|
214
216
|
|
|
215
217
|
headers = {
|
|
@@ -242,13 +244,13 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
242
244
|
|
|
243
245
|
# Prepare query parameters
|
|
244
246
|
params = EnsoRouteShortcutInput(
|
|
245
|
-
chainId=
|
|
247
|
+
chainId=resolved_chain_id,
|
|
246
248
|
amountIn=amountIn,
|
|
247
249
|
tokenIn=tokenIn,
|
|
248
250
|
tokenOut=tokenOut,
|
|
249
251
|
).model_dump(exclude_none=True)
|
|
250
252
|
|
|
251
|
-
params["fromAddress"] =
|
|
253
|
+
params["fromAddress"] = wallet_address
|
|
252
254
|
|
|
253
255
|
response = await client.get(url, headers=headers, params=params)
|
|
254
256
|
response.raise_for_status() # Raise HTTPError for non-2xx responses
|
|
@@ -256,10 +258,12 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
256
258
|
|
|
257
259
|
res = EnsoRouteShortcutOutput(**json_dict)
|
|
258
260
|
res.network = network_name
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
261
|
+
decimals = token_decimals.get(tokenOut[0])
|
|
262
|
+
amount_out = format_amount_with_decimals(
|
|
263
|
+
json_dict.get("amountOut"), decimals
|
|
262
264
|
)
|
|
265
|
+
if amount_out is not None:
|
|
266
|
+
res.amountOut = amount_out
|
|
263
267
|
|
|
264
268
|
if broadcast_requested:
|
|
265
269
|
# Use the wallet provider to send the transaction
|
|
@@ -269,13 +273,13 @@ class EnsoRouteShortcut(EnsoBaseTool):
|
|
|
269
273
|
tx_data = json_dict.get("tx", {})
|
|
270
274
|
if tx_data:
|
|
271
275
|
# Send the transaction using the wallet provider
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
)
|
|
276
|
+
tx_params = {
|
|
277
|
+
"to": tx_data.get("to"),
|
|
278
|
+
"data": tx_data.get("data", "0x"),
|
|
279
|
+
"value": tx_data.get("value", 0),
|
|
280
|
+
"from": wallet_address,
|
|
281
|
+
}
|
|
282
|
+
tx_hash = wallet_provider.send_transaction(tx_params)
|
|
279
283
|
|
|
280
284
|
# Wait for transaction confirmation
|
|
281
285
|
wallet_provider.wait_for_transaction_receipt(tx_hash)
|
intentkit/skills/enso/tokens.py
CHANGED
|
@@ -4,11 +4,7 @@ import httpx
|
|
|
4
4
|
from langchain.tools.base import ToolException
|
|
5
5
|
from pydantic import BaseModel, Field
|
|
6
6
|
|
|
7
|
-
from intentkit.skills.enso.base import
|
|
8
|
-
EnsoBaseTool,
|
|
9
|
-
base_url,
|
|
10
|
-
default_chain_id,
|
|
11
|
-
)
|
|
7
|
+
from intentkit.skills.enso.base import EnsoBaseTool, base_url
|
|
12
8
|
|
|
13
9
|
# Actual Enso output types
|
|
14
10
|
# class UnderlyingToken(BaseModel):
|
|
@@ -50,9 +46,9 @@ from intentkit.skills.enso.base import (
|
|
|
50
46
|
|
|
51
47
|
|
|
52
48
|
class EnsoGetTokensInput(BaseModel):
|
|
53
|
-
chainId: int = Field(
|
|
54
|
-
|
|
55
|
-
description="The blockchain chain ID",
|
|
49
|
+
chainId: int | None = Field(
|
|
50
|
+
None,
|
|
51
|
+
description="The blockchain chain ID. Defaults to the agent's configured network.",
|
|
56
52
|
)
|
|
57
53
|
protocolSlug: str | None = Field(
|
|
58
54
|
None,
|
|
@@ -110,7 +106,10 @@ class TokenResponseCompact(BaseModel):
|
|
|
110
106
|
|
|
111
107
|
|
|
112
108
|
class EnsoGetTokensOutput(BaseModel):
|
|
113
|
-
res: list[TokenResponseCompact]
|
|
109
|
+
res: list[TokenResponseCompact] = Field(
|
|
110
|
+
default_factory=list,
|
|
111
|
+
description="List of token information entries",
|
|
112
|
+
)
|
|
114
113
|
|
|
115
114
|
|
|
116
115
|
class EnsoGetTokens(EnsoBaseTool):
|
|
@@ -138,7 +137,7 @@ class EnsoGetTokens(EnsoBaseTool):
|
|
|
138
137
|
|
|
139
138
|
async def _arun(
|
|
140
139
|
self,
|
|
141
|
-
chainId: int =
|
|
140
|
+
chainId: int | None = None,
|
|
142
141
|
protocolSlug: str | None = None,
|
|
143
142
|
**kwargs,
|
|
144
143
|
) -> EnsoGetTokensOutput:
|
|
@@ -156,15 +155,17 @@ class EnsoGetTokens(EnsoBaseTool):
|
|
|
156
155
|
|
|
157
156
|
context = self.get_context()
|
|
158
157
|
agent_id = context.agent_id
|
|
158
|
+
resolved_chain_id = self.resolve_chain_id(context, chainId)
|
|
159
159
|
api_token = self.get_api_token(context)
|
|
160
160
|
main_tokens = self.get_main_tokens(context)
|
|
161
|
+
main_tokens_upper = {token.upper() for token in main_tokens}
|
|
161
162
|
headers = {
|
|
162
163
|
"accept": "application/json",
|
|
163
164
|
"Authorization": f"Bearer {api_token}",
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
params = EnsoGetTokensInput(
|
|
167
|
-
chainId=
|
|
168
|
+
chainId=resolved_chain_id,
|
|
168
169
|
protocolSlug=protocolSlug,
|
|
169
170
|
).model_dump(exclude_none=True)
|
|
170
171
|
|
|
@@ -186,19 +187,21 @@ class EnsoGetTokens(EnsoBaseTool):
|
|
|
186
187
|
token_decimals = {}
|
|
187
188
|
|
|
188
189
|
# filter the main tokens from config or the ones that have apy assigned.
|
|
189
|
-
res = EnsoGetTokensOutput(
|
|
190
|
-
for item in json_dict
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
res = EnsoGetTokensOutput()
|
|
191
|
+
for item in json_dict.get("data", []):
|
|
192
|
+
symbol = item.get("symbol", "").upper()
|
|
193
|
+
has_apy = bool(item.get("apy"))
|
|
194
|
+
if has_apy or symbol in main_tokens_upper:
|
|
193
195
|
token_response = TokenResponseCompact(**item)
|
|
194
196
|
res.res.append(token_response)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
if token_response.address:
|
|
198
|
+
token_decimals[token_response.address] = (
|
|
199
|
+
token_response.decimals
|
|
200
|
+
)
|
|
201
|
+
if token_response.underlyingTokens:
|
|
200
202
|
for u_token in token_response.underlyingTokens:
|
|
201
|
-
|
|
203
|
+
if u_token.address:
|
|
204
|
+
token_decimals[u_token.address] = u_token.decimals
|
|
202
205
|
|
|
203
206
|
await self.skill_store.save_agent_skill_data(
|
|
204
207
|
agent_id,
|
intentkit/skills/enso/wallet.py
CHANGED
|
@@ -4,23 +4,13 @@ import httpx
|
|
|
4
4
|
from langchain.tools.base import ToolException
|
|
5
5
|
from pydantic import BaseModel, Field
|
|
6
6
|
|
|
7
|
-
from .base import EnsoBaseTool, base_url
|
|
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,15 +29,7 @@ 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 = (
|
|
@@ -59,61 +39,48 @@ class EnsoGetWalletBalances(EnsoBaseTool):
|
|
|
59
39
|
|
|
60
40
|
async def _arun(
|
|
61
41
|
self,
|
|
62
|
-
chainId: int =
|
|
63
|
-
**
|
|
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
|
-
|
|
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=
|
|
85
|
-
|
|
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
|
-
|
|
91
|
-
|
|
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
|
|
105
|
-
raise ToolException(f"error from Enso API: {
|
|
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] =
|
|
110
|
+
args_schema: Type[BaseModel] = EnsoGetApprovalsInput
|
|
154
111
|
|
|
155
112
|
async def _arun(
|
|
156
113
|
self,
|
|
157
|
-
chainId: int =
|
|
158
|
-
|
|
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
|
-
|
|
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=
|
|
183
|
-
|
|
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
|
-
|
|
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
|
|
212
|
-
raise ToolException(f"error from Enso API: {
|
|
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(
|
|
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 =
|
|
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
|
+
)
|
|
271
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 =
|
|
296
|
-
|
|
202
|
+
chainId: int | None = None,
|
|
203
|
+
routingStrategy: Literal["ensowallet", "router", "delegate"] | None = None,
|
|
204
|
+
**_: object,
|
|
297
205
|
) -> 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"
|
|
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
|
-
|
|
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=
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
with httpx.Client() as client:
|
|
224
|
+
async with httpx.AsyncClient() as client:
|
|
336
225
|
try:
|
|
337
|
-
|
|
338
|
-
|
|
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
|
|
379
|
-
raise ToolException(f"error from Enso API: {
|
|
263
|
+
except Exception as exc: # pragma: no cover - defensive
|
|
264
|
+
raise ToolException(f"error from Enso API: {exc}") from exc
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: intentkit
|
|
3
|
-
Version: 0.7.5.
|
|
3
|
+
Version: 0.7.5.dev18
|
|
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
|