@smartagentkit/langchain 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/index.d.mts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +203 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +176 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SmartAgentKit Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @smartagentkit/langchain
|
|
2
|
+
|
|
3
|
+
LangChain integration for SmartAgentKit. Provides pre-built tools that let LangChain agents interact with policy-governed smart wallets: check balances, send transactions, query spending allowances, and monitor wallet status.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @smartagentkit/langchain @smartagentkit/sdk @langchain/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { SmartAgentKitClient } from "@smartagentkit/sdk";
|
|
15
|
+
import { createSmartAgentKitTools } from "@smartagentkit/langchain";
|
|
16
|
+
import { baseSepolia } from "viem/chains";
|
|
17
|
+
|
|
18
|
+
const client = new SmartAgentKitClient({
|
|
19
|
+
chain: baseSepolia,
|
|
20
|
+
rpcUrl: "https://...",
|
|
21
|
+
bundlerUrl: "https://...",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const wallet = await client.createWallet({ /* ... */ });
|
|
25
|
+
const tools = createSmartAgentKitTools(client, wallet);
|
|
26
|
+
|
|
27
|
+
// Use with any LangChain agent
|
|
28
|
+
// tools: check_wallet_balance, check_spending_allowance,
|
|
29
|
+
// send_transaction, check_wallet_status
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Tools
|
|
33
|
+
|
|
34
|
+
- **check_wallet_balance** - Get ETH balance of the agent wallet
|
|
35
|
+
- **check_spending_allowance** - Query remaining spending limit for a token
|
|
36
|
+
- **send_transaction** - Execute a transaction through the smart wallet
|
|
37
|
+
- **check_wallet_status** - Check if the wallet is paused
|
|
38
|
+
|
|
39
|
+
## Documentation
|
|
40
|
+
|
|
41
|
+
See the [main repository](https://github.com/smartagentkit/smartagentkit) for full documentation, examples, and the technical specification.
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
2
|
+
import { ISmartAgentKitClient } from '@smartagentkit/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates LangChain tools for interacting with a SmartAgentKit wallet.
|
|
6
|
+
*
|
|
7
|
+
* Returns 5 tools that an LLM agent can use to manage and transact
|
|
8
|
+
* from a policy-governed smart wallet:
|
|
9
|
+
*
|
|
10
|
+
* - **check_wallet_balance** — Get ETH balance
|
|
11
|
+
* - **check_spending_allowance** — Query remaining spending limit for a token
|
|
12
|
+
* - **send_transaction** — Execute an on-chain transaction
|
|
13
|
+
* - **send_batch_transaction** — Execute multiple calls atomically
|
|
14
|
+
* - **check_wallet_status** — Check if wallet is paused
|
|
15
|
+
*
|
|
16
|
+
* @param client - An initialized SmartAgentKitClient
|
|
17
|
+
* @param walletAddress - The smart wallet address to operate on
|
|
18
|
+
* @param sessionKey - Optional session key private key for signing transactions
|
|
19
|
+
* @returns Array of DynamicStructuredTool instances for use with LangChain agents
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { createSmartAgentKitTools } from "@smartagentkit/langchain";
|
|
24
|
+
* import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
25
|
+
*
|
|
26
|
+
* const tools = createSmartAgentKitTools(client, wallet.address, sessionKey);
|
|
27
|
+
* const agent = createReactAgent({ llm: chatModel, tools });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare function createSmartAgentKitTools(client: ISmartAgentKitClient, walletAddress: string, sessionKey?: string): DynamicStructuredTool[];
|
|
31
|
+
|
|
32
|
+
export { createSmartAgentKitTools };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
2
|
+
import { ISmartAgentKitClient } from '@smartagentkit/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates LangChain tools for interacting with a SmartAgentKit wallet.
|
|
6
|
+
*
|
|
7
|
+
* Returns 5 tools that an LLM agent can use to manage and transact
|
|
8
|
+
* from a policy-governed smart wallet:
|
|
9
|
+
*
|
|
10
|
+
* - **check_wallet_balance** — Get ETH balance
|
|
11
|
+
* - **check_spending_allowance** — Query remaining spending limit for a token
|
|
12
|
+
* - **send_transaction** — Execute an on-chain transaction
|
|
13
|
+
* - **send_batch_transaction** — Execute multiple calls atomically
|
|
14
|
+
* - **check_wallet_status** — Check if wallet is paused
|
|
15
|
+
*
|
|
16
|
+
* @param client - An initialized SmartAgentKitClient
|
|
17
|
+
* @param walletAddress - The smart wallet address to operate on
|
|
18
|
+
* @param sessionKey - Optional session key private key for signing transactions
|
|
19
|
+
* @returns Array of DynamicStructuredTool instances for use with LangChain agents
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { createSmartAgentKitTools } from "@smartagentkit/langchain";
|
|
24
|
+
* import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
|
25
|
+
*
|
|
26
|
+
* const tools = createSmartAgentKitTools(client, wallet.address, sessionKey);
|
|
27
|
+
* const agent = createReactAgent({ llm: chatModel, tools });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare function createSmartAgentKitTools(client: ISmartAgentKitClient, walletAddress: string, sessionKey?: string): DynamicStructuredTool[];
|
|
31
|
+
|
|
32
|
+
export { createSmartAgentKitTools };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createSmartAgentKitTools: () => createSmartAgentKitTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/tools.ts
|
|
28
|
+
var import_tools = require("@langchain/core/tools");
|
|
29
|
+
var import_zod = require("zod");
|
|
30
|
+
var addressSchema = import_zod.z.string().regex(/^0x[0-9a-fA-F]{40}$/, "Must be a 0x-prefixed 20-byte hex address");
|
|
31
|
+
var weiValueSchema = import_zod.z.string().regex(/^\d+$/, "Must be a non-negative integer string (wei)");
|
|
32
|
+
var calldataSchema = import_zod.z.string().regex(/^0x([0-9a-fA-F]{2})*$/, "Must be 0x-prefixed hex calldata (even length)");
|
|
33
|
+
function createSmartAgentKitTools(client, walletAddress, sessionKey) {
|
|
34
|
+
const address = walletAddress;
|
|
35
|
+
const checkWalletBalance = new import_tools.DynamicStructuredTool({
|
|
36
|
+
name: "check_wallet_balance",
|
|
37
|
+
description: "Check the ETH balance of the agent's smart wallet. Returns the balance in ETH (assuming 18 decimals). The raw wei value is also returned for precision. Use this before sending transactions to ensure sufficient funds.",
|
|
38
|
+
schema: import_zod.z.object({}),
|
|
39
|
+
func: async () => {
|
|
40
|
+
try {
|
|
41
|
+
const balances = await client.getBalances(address);
|
|
42
|
+
const ethBalance = Number(balances.eth) / 1e18;
|
|
43
|
+
return JSON.stringify({
|
|
44
|
+
wallet: walletAddress,
|
|
45
|
+
eth: ethBalance.toString(),
|
|
46
|
+
ethWei: balances.eth.toString()
|
|
47
|
+
});
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return JSON.stringify({
|
|
50
|
+
error: error instanceof Error ? error.message : String(error)
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const checkSpendingAllowance = new import_tools.DynamicStructuredTool({
|
|
56
|
+
name: "check_spending_allowance",
|
|
57
|
+
description: 'Check how much spending allowance remains for a token on the wallet. The wallet has policy-enforced spending limits per token per time window. Use this to verify you can spend a certain amount before sending a transaction. Use "0x0000000000000000000000000000000000000000" for native ETH.',
|
|
58
|
+
schema: import_zod.z.object({
|
|
59
|
+
token: addressSchema.describe(
|
|
60
|
+
"Token contract address. Use 0x0000000000000000000000000000000000000000 for native ETH."
|
|
61
|
+
)
|
|
62
|
+
}),
|
|
63
|
+
func: async ({ token }) => {
|
|
64
|
+
try {
|
|
65
|
+
const remaining = await client.getRemainingAllowance(
|
|
66
|
+
address,
|
|
67
|
+
token
|
|
68
|
+
);
|
|
69
|
+
const remainingEth = Number(remaining) / 1e18;
|
|
70
|
+
return JSON.stringify({
|
|
71
|
+
wallet: walletAddress,
|
|
72
|
+
token,
|
|
73
|
+
remainingWei: remaining.toString(),
|
|
74
|
+
remaining: remainingEth.toString()
|
|
75
|
+
});
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return JSON.stringify({
|
|
78
|
+
error: error instanceof Error ? error.message : String(error)
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
const sendTransaction = new import_tools.DynamicStructuredTool({
|
|
84
|
+
name: "send_transaction",
|
|
85
|
+
description: "Send a transaction from the agent's smart wallet. The transaction is executed as a UserOperation through ERC-4337 and is subject to the wallet's policy constraints (spending limits, allowlist, pause state). All values are in wei (1 ETH = 1e18 wei). Returns the transaction hash on success.",
|
|
86
|
+
schema: import_zod.z.object({
|
|
87
|
+
target: addressSchema.describe(
|
|
88
|
+
"Target contract address to call (0x-prefixed 20-byte hex)"
|
|
89
|
+
),
|
|
90
|
+
value: weiValueSchema.optional().describe(
|
|
91
|
+
"ETH value to send in wei (as string). Defaults to '0'. Example: '1000000000000000' for 0.001 ETH."
|
|
92
|
+
),
|
|
93
|
+
data: calldataSchema.optional().describe(
|
|
94
|
+
"Calldata for the transaction (0x-prefixed hex). Defaults to '0x' for simple ETH transfer."
|
|
95
|
+
)
|
|
96
|
+
}),
|
|
97
|
+
func: async ({ target, value, data }) => {
|
|
98
|
+
try {
|
|
99
|
+
const wallet = {
|
|
100
|
+
address,
|
|
101
|
+
owner: address,
|
|
102
|
+
// Resolved from connected wallet
|
|
103
|
+
chain: {},
|
|
104
|
+
// Not used in execute
|
|
105
|
+
isDeployed: true,
|
|
106
|
+
policies: [],
|
|
107
|
+
sessions: []
|
|
108
|
+
};
|
|
109
|
+
const txHash = await client.execute(wallet, {
|
|
110
|
+
target,
|
|
111
|
+
value: value ? BigInt(value) : 0n,
|
|
112
|
+
data: data ?? "0x",
|
|
113
|
+
sessionKey
|
|
114
|
+
});
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
success: true,
|
|
117
|
+
transactionHash: txHash
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return JSON.stringify({
|
|
121
|
+
success: false,
|
|
122
|
+
error: error instanceof Error ? error.message : String(error)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
const sendBatchTransaction = new import_tools.DynamicStructuredTool({
|
|
128
|
+
name: "send_batch_transaction",
|
|
129
|
+
description: "Send multiple transactions atomically from the agent's smart wallet. All calls are bundled into a single UserOperation and either all succeed or all revert. Useful for approve+swap, multi-transfer, or any multi-step operation. Subject to the wallet's policy constraints. All values are in wei.",
|
|
130
|
+
schema: import_zod.z.object({
|
|
131
|
+
calls: import_zod.z.array(
|
|
132
|
+
import_zod.z.object({
|
|
133
|
+
target: addressSchema.describe(
|
|
134
|
+
"Target contract address (0x-prefixed 20-byte hex)"
|
|
135
|
+
),
|
|
136
|
+
value: weiValueSchema.optional().describe("ETH value in wei (as string). Defaults to '0'."),
|
|
137
|
+
data: import_zod.z.string().optional().describe("Calldata (0x-prefixed hex). Defaults to '0x'.")
|
|
138
|
+
})
|
|
139
|
+
).min(1).describe("Array of calls to execute atomically")
|
|
140
|
+
}),
|
|
141
|
+
func: async ({ calls }) => {
|
|
142
|
+
try {
|
|
143
|
+
const wallet = {
|
|
144
|
+
address,
|
|
145
|
+
owner: address,
|
|
146
|
+
chain: {},
|
|
147
|
+
isDeployed: true,
|
|
148
|
+
policies: [],
|
|
149
|
+
sessions: []
|
|
150
|
+
};
|
|
151
|
+
const txHash = await client.executeBatch(wallet, {
|
|
152
|
+
calls: calls.map((c) => ({
|
|
153
|
+
target: c.target,
|
|
154
|
+
value: c.value ? BigInt(c.value) : 0n,
|
|
155
|
+
data: c.data ?? "0x"
|
|
156
|
+
})),
|
|
157
|
+
sessionKey
|
|
158
|
+
});
|
|
159
|
+
return JSON.stringify({
|
|
160
|
+
success: true,
|
|
161
|
+
transactionHash: txHash,
|
|
162
|
+
callCount: calls.length
|
|
163
|
+
});
|
|
164
|
+
} catch (error) {
|
|
165
|
+
return JSON.stringify({
|
|
166
|
+
success: false,
|
|
167
|
+
error: error instanceof Error ? error.message : String(error)
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
const checkWalletStatus = new import_tools.DynamicStructuredTool({
|
|
173
|
+
name: "check_wallet_status",
|
|
174
|
+
description: "Check if the agent's smart wallet is currently paused. A paused wallet cannot execute any transactions. The guardian can pause the wallet in emergencies.",
|
|
175
|
+
schema: import_zod.z.object({}),
|
|
176
|
+
func: async () => {
|
|
177
|
+
try {
|
|
178
|
+
const paused = await client.isPaused(address);
|
|
179
|
+
return JSON.stringify({
|
|
180
|
+
wallet: walletAddress,
|
|
181
|
+
paused,
|
|
182
|
+
status: paused ? "paused" : "active"
|
|
183
|
+
});
|
|
184
|
+
} catch (error) {
|
|
185
|
+
return JSON.stringify({
|
|
186
|
+
error: error instanceof Error ? error.message : String(error)
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return [
|
|
192
|
+
checkWalletBalance,
|
|
193
|
+
checkSpendingAllowance,
|
|
194
|
+
sendTransaction,
|
|
195
|
+
sendBatchTransaction,
|
|
196
|
+
checkWalletStatus
|
|
197
|
+
];
|
|
198
|
+
}
|
|
199
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
200
|
+
0 && (module.exports = {
|
|
201
|
+
createSmartAgentKitTools
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tools.ts"],"sourcesContent":["export { createSmartAgentKitTools } from \"./tools.js\";\n","import { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { ISmartAgentKitClient } from \"@smartagentkit/sdk\";\n\n// Reusable Zod pattern for 0x-prefixed Ethereum addresses (20 bytes)\nconst addressSchema = z\n .string()\n .regex(/^0x[0-9a-fA-F]{40}$/, \"Must be a 0x-prefixed 20-byte hex address\");\n\n// Reusable Zod pattern for non-negative integer strings (wei values)\nconst weiValueSchema = z\n .string()\n .regex(/^\\d+$/, \"Must be a non-negative integer string (wei)\");\n\n// Reusable Zod pattern for 0x-prefixed hex calldata (even-length)\nconst calldataSchema = z\n .string()\n .regex(/^0x([0-9a-fA-F]{2})*$/, \"Must be 0x-prefixed hex calldata (even length)\");\n\n/**\n * Creates LangChain tools for interacting with a SmartAgentKit wallet.\n *\n * Returns 5 tools that an LLM agent can use to manage and transact\n * from a policy-governed smart wallet:\n *\n * - **check_wallet_balance** — Get ETH balance\n * - **check_spending_allowance** — Query remaining spending limit for a token\n * - **send_transaction** — Execute an on-chain transaction\n * - **send_batch_transaction** — Execute multiple calls atomically\n * - **check_wallet_status** — Check if wallet is paused\n *\n * @param client - An initialized SmartAgentKitClient\n * @param walletAddress - The smart wallet address to operate on\n * @param sessionKey - Optional session key private key for signing transactions\n * @returns Array of DynamicStructuredTool instances for use with LangChain agents\n *\n * @example\n * ```ts\n * import { createSmartAgentKitTools } from \"@smartagentkit/langchain\";\n * import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n *\n * const tools = createSmartAgentKitTools(client, wallet.address, sessionKey);\n * const agent = createReactAgent({ llm: chatModel, tools });\n * ```\n */\nexport function createSmartAgentKitTools(\n client: ISmartAgentKitClient,\n walletAddress: string,\n sessionKey?: string,\n): DynamicStructuredTool[] {\n const address = walletAddress as `0x${string}`;\n\n // ─── check_wallet_balance ─────────────────────────────────────\n\n const checkWalletBalance = new DynamicStructuredTool({\n name: \"check_wallet_balance\",\n description:\n \"Check the ETH balance of the agent's smart wallet. \" +\n \"Returns the balance in ETH (assuming 18 decimals). \" +\n \"The raw wei value is also returned for precision. \" +\n \"Use this before sending transactions to ensure sufficient funds.\",\n schema: z.object({}),\n func: async () => {\n try {\n const balances = await client.getBalances(address);\n // Note: Division by 1e18 assumes 18 decimals (correct for native ETH).\n // For ERC-20 tokens, use the raw wei value and the token's actual decimals.\n const ethBalance = Number(balances.eth) / 1e18;\n return JSON.stringify({\n wallet: walletAddress,\n eth: ethBalance.toString(),\n ethWei: balances.eth.toString(),\n });\n } catch (error) {\n return JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── check_spending_allowance ────────────────────────────────\n\n const checkSpendingAllowance = new DynamicStructuredTool({\n name: \"check_spending_allowance\",\n description:\n \"Check how much spending allowance remains for a token on the wallet. \" +\n \"The wallet has policy-enforced spending limits per token per time window. \" +\n \"Use this to verify you can spend a certain amount before sending a transaction. \" +\n 'Use \"0x0000000000000000000000000000000000000000\" for native ETH.',\n schema: z.object({\n token: addressSchema.describe(\n \"Token contract address. Use 0x0000000000000000000000000000000000000000 for native ETH.\",\n ),\n }),\n func: async ({ token }) => {\n try {\n const remaining = await client.getRemainingAllowance(\n address,\n token as `0x${string}`,\n );\n // Note: Division by 1e18 assumes 18 decimals (correct for native ETH).\n // For tokens with different decimals (e.g., USDC = 6), use remainingWei\n // and divide by the token's actual decimal factor.\n const remainingEth = Number(remaining) / 1e18;\n return JSON.stringify({\n wallet: walletAddress,\n token,\n remainingWei: remaining.toString(),\n remaining: remainingEth.toString(),\n });\n } catch (error) {\n return JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── send_transaction ─────────────────────────────────────────\n\n const sendTransaction = new DynamicStructuredTool({\n name: \"send_transaction\",\n description:\n \"Send a transaction from the agent's smart wallet. \" +\n \"The transaction is executed as a UserOperation through ERC-4337 \" +\n \"and is subject to the wallet's policy constraints (spending limits, \" +\n \"allowlist, pause state). All values are in wei (1 ETH = 1e18 wei). \" +\n \"Returns the transaction hash on success.\",\n schema: z.object({\n target: addressSchema.describe(\n \"Target contract address to call (0x-prefixed 20-byte hex)\",\n ),\n value: weiValueSchema\n .optional()\n .describe(\n \"ETH value to send in wei (as string). Defaults to '0'. Example: '1000000000000000' for 0.001 ETH.\",\n ),\n data: calldataSchema\n .optional()\n .describe(\n \"Calldata for the transaction (0x-prefixed hex). Defaults to '0x' for simple ETH transfer.\",\n ),\n }),\n func: async ({ target, value, data }) => {\n try {\n const wallet = {\n address,\n owner: address, // Resolved from connected wallet\n chain: {} as never, // Not used in execute\n isDeployed: true,\n policies: [],\n sessions: [],\n };\n\n const txHash = await client.execute(wallet, {\n target: target as `0x${string}`,\n value: value ? BigInt(value) : 0n,\n data: (data as `0x${string}`) ?? \"0x\",\n sessionKey: sessionKey as `0x${string}` | undefined,\n });\n\n return JSON.stringify({\n success: true,\n transactionHash: txHash,\n });\n } catch (error) {\n return JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── send_batch_transaction ───────────────────────────────────\n\n const sendBatchTransaction = new DynamicStructuredTool({\n name: \"send_batch_transaction\",\n description:\n \"Send multiple transactions atomically from the agent's smart wallet. \" +\n \"All calls are bundled into a single UserOperation and either all succeed or all revert. \" +\n \"Useful for approve+swap, multi-transfer, or any multi-step operation. \" +\n \"Subject to the wallet's policy constraints. All values are in wei.\",\n schema: z.object({\n calls: z\n .array(\n z.object({\n target: addressSchema.describe(\n \"Target contract address (0x-prefixed 20-byte hex)\",\n ),\n value: weiValueSchema\n .optional()\n .describe(\"ETH value in wei (as string). Defaults to '0'.\"),\n data: z\n .string()\n .optional()\n .describe(\"Calldata (0x-prefixed hex). Defaults to '0x'.\"),\n }),\n )\n .min(1)\n .describe(\"Array of calls to execute atomically\"),\n }),\n func: async ({ calls }) => {\n try {\n const wallet = {\n address,\n owner: address,\n chain: {} as never,\n isDeployed: true,\n policies: [],\n sessions: [],\n };\n\n const txHash = await client.executeBatch(wallet, {\n calls: calls.map((c) => ({\n target: c.target as `0x${string}`,\n value: c.value ? BigInt(c.value) : 0n,\n data: (c.data as `0x${string}`) ?? \"0x\",\n })),\n sessionKey: sessionKey as `0x${string}` | undefined,\n });\n\n return JSON.stringify({\n success: true,\n transactionHash: txHash,\n callCount: calls.length,\n });\n } catch (error) {\n return JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── check_wallet_status ─────────────────────────────────────\n\n const checkWalletStatus = new DynamicStructuredTool({\n name: \"check_wallet_status\",\n description:\n \"Check if the agent's smart wallet is currently paused. \" +\n \"A paused wallet cannot execute any transactions. \" +\n \"The guardian can pause the wallet in emergencies.\",\n schema: z.object({}),\n func: async () => {\n try {\n const paused = await client.isPaused(address);\n return JSON.stringify({\n wallet: walletAddress,\n paused,\n status: paused ? \"paused\" : \"active\",\n });\n } catch (error) {\n return JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n return [\n checkWalletBalance,\n checkSpendingAllowance,\n sendTransaction,\n sendBatchTransaction,\n checkWalletStatus,\n ];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAsC;AACtC,iBAAkB;AAIlB,IAAM,gBAAgB,aACnB,OAAO,EACP,MAAM,uBAAuB,2CAA2C;AAG3E,IAAM,iBAAiB,aACpB,OAAO,EACP,MAAM,SAAS,6CAA6C;AAG/D,IAAM,iBAAiB,aACpB,OAAO,EACP,MAAM,yBAAyB,gDAAgD;AA4B3E,SAAS,yBACd,QACA,eACA,YACyB;AACzB,QAAM,UAAU;AAIhB,QAAM,qBAAqB,IAAI,mCAAsB;AAAA,IACnD,MAAM;AAAA,IACN,aACE;AAAA,IAIF,QAAQ,aAAE,OAAO,CAAC,CAAC;AAAA,IACnB,MAAM,YAAY;AAChB,UAAI;AACF,cAAM,WAAW,MAAM,OAAO,YAAY,OAAO;AAGjD,cAAM,aAAa,OAAO,SAAS,GAAG,IAAI;AAC1C,eAAO,KAAK,UAAU;AAAA,UACpB,QAAQ;AAAA,UACR,KAAK,WAAW,SAAS;AAAA,UACzB,QAAQ,SAAS,IAAI,SAAS;AAAA,QAChC,CAAC;AAAA,MACH,SAAS,OAAO;AACd,eAAO,KAAK,UAAU;AAAA,UACpB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAID,QAAM,yBAAyB,IAAI,mCAAsB;AAAA,IACvD,MAAM;AAAA,IACN,aACE;AAAA,IAIF,QAAQ,aAAE,OAAO;AAAA,MACf,OAAO,cAAc;AAAA,QACnB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACD,MAAM,OAAO,EAAE,MAAM,MAAM;AACzB,UAAI;AACF,cAAM,YAAY,MAAM,OAAO;AAAA,UAC7B;AAAA,UACA;AAAA,QACF;AAIA,cAAM,eAAe,OAAO,SAAS,IAAI;AACzC,eAAO,KAAK,UAAU;AAAA,UACpB,QAAQ;AAAA,UACR;AAAA,UACA,cAAc,UAAU,SAAS;AAAA,UACjC,WAAW,aAAa,SAAS;AAAA,QACnC,CAAC;AAAA,MACH,SAAS,OAAO;AACd,eAAO,KAAK,UAAU;AAAA,UACpB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAID,QAAM,kBAAkB,IAAI,mCAAsB;AAAA,IAChD,MAAM;AAAA,IACN,aACE;AAAA,IAKF,QAAQ,aAAE,OAAO;AAAA,MACf,QAAQ,cAAc;AAAA,QACpB;AAAA,MACF;AAAA,MACA,OAAO,eACJ,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,MAAM,eACH,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,IACJ,CAAC;AAAA,IACD,MAAM,OAAO,EAAE,QAAQ,OAAO,KAAK,MAAM;AACvC,UAAI;AACF,cAAM,SAAS;AAAA,UACb;AAAA,UACA,OAAO;AAAA;AAAA,UACP,OAAO,CAAC;AAAA;AAAA,UACR,YAAY;AAAA,UACZ,UAAU,CAAC;AAAA,UACX,UAAU,CAAC;AAAA,QACb;AAEA,cAAM,SAAS,MAAM,OAAO,QAAQ,QAAQ;AAAA,UAC1C;AAAA,UACA,OAAO,QAAQ,OAAO,KAAK,IAAI;AAAA,UAC/B,MAAO,QAA0B;AAAA,UACjC;AAAA,QACF,CAAC;AAED,eAAO,KAAK,UAAU;AAAA,UACpB,SAAS;AAAA,UACT,iBAAiB;AAAA,QACnB,CAAC;AAAA,MACH,SAAS,OAAO;AACd,eAAO,KAAK,UAAU;AAAA,UACpB,SAAS;AAAA,UACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAID,QAAM,uBAAuB,IAAI,mCAAsB;AAAA,IACrD,MAAM;AAAA,IACN,aACE;AAAA,IAIF,QAAQ,aAAE,OAAO;AAAA,MACf,OAAO,aACJ;AAAA,QACC,aAAE,OAAO;AAAA,UACP,QAAQ,cAAc;AAAA,YACpB;AAAA,UACF;AAAA,UACA,OAAO,eACJ,SAAS,EACT,SAAS,gDAAgD;AAAA,UAC5D,MAAM,aACH,OAAO,EACP,SAAS,EACT,SAAS,+CAA+C;AAAA,QAC7D,CAAC;AAAA,MACH,EACC,IAAI,CAAC,EACL,SAAS,sCAAsC;AAAA,IACpD,CAAC;AAAA,IACD,MAAM,OAAO,EAAE,MAAM,MAAM;AACzB,UAAI;AACF,cAAM,SAAS;AAAA,UACb;AAAA,UACA,OAAO;AAAA,UACP,OAAO,CAAC;AAAA,UACR,YAAY;AAAA,UACZ,UAAU,CAAC;AAAA,UACX,UAAU,CAAC;AAAA,QACb;AAEA,cAAM,SAAS,MAAM,OAAO,aAAa,QAAQ;AAAA,UAC/C,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,YACvB,QAAQ,EAAE;AAAA,YACV,OAAO,EAAE,QAAQ,OAAO,EAAE,KAAK,IAAI;AAAA,YACnC,MAAO,EAAE,QAA0B;AAAA,UACrC,EAAE;AAAA,UACF;AAAA,QACF,CAAC;AAED,eAAO,KAAK,UAAU;AAAA,UACpB,SAAS;AAAA,UACT,iBAAiB;AAAA,UACjB,WAAW,MAAM;AAAA,QACnB,CAAC;AAAA,MACH,SAAS,OAAO;AACd,eAAO,KAAK,UAAU;AAAA,UACpB,SAAS;AAAA,UACT,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAID,QAAM,oBAAoB,IAAI,mCAAsB;AAAA,IAClD,MAAM;AAAA,IACN,aACE;AAAA,IAGF,QAAQ,aAAE,OAAO,CAAC,CAAC;AAAA,IACnB,MAAM,YAAY;AAChB,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,SAAS,OAAO;AAC5C,eAAO,KAAK,UAAU;AAAA,UACpB,QAAQ;AAAA,UACR;AAAA,UACA,QAAQ,SAAS,WAAW;AAAA,QAC9B,CAAC;AAAA,MACH,SAAS,OAAO;AACd,eAAO,KAAK,UAAU;AAAA,UACpB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// src/tools.ts
|
|
2
|
+
import { DynamicStructuredTool } from "@langchain/core/tools";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
var addressSchema = z.string().regex(/^0x[0-9a-fA-F]{40}$/, "Must be a 0x-prefixed 20-byte hex address");
|
|
5
|
+
var weiValueSchema = z.string().regex(/^\d+$/, "Must be a non-negative integer string (wei)");
|
|
6
|
+
var calldataSchema = z.string().regex(/^0x([0-9a-fA-F]{2})*$/, "Must be 0x-prefixed hex calldata (even length)");
|
|
7
|
+
function createSmartAgentKitTools(client, walletAddress, sessionKey) {
|
|
8
|
+
const address = walletAddress;
|
|
9
|
+
const checkWalletBalance = new DynamicStructuredTool({
|
|
10
|
+
name: "check_wallet_balance",
|
|
11
|
+
description: "Check the ETH balance of the agent's smart wallet. Returns the balance in ETH (assuming 18 decimals). The raw wei value is also returned for precision. Use this before sending transactions to ensure sufficient funds.",
|
|
12
|
+
schema: z.object({}),
|
|
13
|
+
func: async () => {
|
|
14
|
+
try {
|
|
15
|
+
const balances = await client.getBalances(address);
|
|
16
|
+
const ethBalance = Number(balances.eth) / 1e18;
|
|
17
|
+
return JSON.stringify({
|
|
18
|
+
wallet: walletAddress,
|
|
19
|
+
eth: ethBalance.toString(),
|
|
20
|
+
ethWei: balances.eth.toString()
|
|
21
|
+
});
|
|
22
|
+
} catch (error) {
|
|
23
|
+
return JSON.stringify({
|
|
24
|
+
error: error instanceof Error ? error.message : String(error)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
const checkSpendingAllowance = new DynamicStructuredTool({
|
|
30
|
+
name: "check_spending_allowance",
|
|
31
|
+
description: 'Check how much spending allowance remains for a token on the wallet. The wallet has policy-enforced spending limits per token per time window. Use this to verify you can spend a certain amount before sending a transaction. Use "0x0000000000000000000000000000000000000000" for native ETH.',
|
|
32
|
+
schema: z.object({
|
|
33
|
+
token: addressSchema.describe(
|
|
34
|
+
"Token contract address. Use 0x0000000000000000000000000000000000000000 for native ETH."
|
|
35
|
+
)
|
|
36
|
+
}),
|
|
37
|
+
func: async ({ token }) => {
|
|
38
|
+
try {
|
|
39
|
+
const remaining = await client.getRemainingAllowance(
|
|
40
|
+
address,
|
|
41
|
+
token
|
|
42
|
+
);
|
|
43
|
+
const remainingEth = Number(remaining) / 1e18;
|
|
44
|
+
return JSON.stringify({
|
|
45
|
+
wallet: walletAddress,
|
|
46
|
+
token,
|
|
47
|
+
remainingWei: remaining.toString(),
|
|
48
|
+
remaining: remainingEth.toString()
|
|
49
|
+
});
|
|
50
|
+
} catch (error) {
|
|
51
|
+
return JSON.stringify({
|
|
52
|
+
error: error instanceof Error ? error.message : String(error)
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const sendTransaction = new DynamicStructuredTool({
|
|
58
|
+
name: "send_transaction",
|
|
59
|
+
description: "Send a transaction from the agent's smart wallet. The transaction is executed as a UserOperation through ERC-4337 and is subject to the wallet's policy constraints (spending limits, allowlist, pause state). All values are in wei (1 ETH = 1e18 wei). Returns the transaction hash on success.",
|
|
60
|
+
schema: z.object({
|
|
61
|
+
target: addressSchema.describe(
|
|
62
|
+
"Target contract address to call (0x-prefixed 20-byte hex)"
|
|
63
|
+
),
|
|
64
|
+
value: weiValueSchema.optional().describe(
|
|
65
|
+
"ETH value to send in wei (as string). Defaults to '0'. Example: '1000000000000000' for 0.001 ETH."
|
|
66
|
+
),
|
|
67
|
+
data: calldataSchema.optional().describe(
|
|
68
|
+
"Calldata for the transaction (0x-prefixed hex). Defaults to '0x' for simple ETH transfer."
|
|
69
|
+
)
|
|
70
|
+
}),
|
|
71
|
+
func: async ({ target, value, data }) => {
|
|
72
|
+
try {
|
|
73
|
+
const wallet = {
|
|
74
|
+
address,
|
|
75
|
+
owner: address,
|
|
76
|
+
// Resolved from connected wallet
|
|
77
|
+
chain: {},
|
|
78
|
+
// Not used in execute
|
|
79
|
+
isDeployed: true,
|
|
80
|
+
policies: [],
|
|
81
|
+
sessions: []
|
|
82
|
+
};
|
|
83
|
+
const txHash = await client.execute(wallet, {
|
|
84
|
+
target,
|
|
85
|
+
value: value ? BigInt(value) : 0n,
|
|
86
|
+
data: data ?? "0x",
|
|
87
|
+
sessionKey
|
|
88
|
+
});
|
|
89
|
+
return JSON.stringify({
|
|
90
|
+
success: true,
|
|
91
|
+
transactionHash: txHash
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
return JSON.stringify({
|
|
95
|
+
success: false,
|
|
96
|
+
error: error instanceof Error ? error.message : String(error)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
const sendBatchTransaction = new DynamicStructuredTool({
|
|
102
|
+
name: "send_batch_transaction",
|
|
103
|
+
description: "Send multiple transactions atomically from the agent's smart wallet. All calls are bundled into a single UserOperation and either all succeed or all revert. Useful for approve+swap, multi-transfer, or any multi-step operation. Subject to the wallet's policy constraints. All values are in wei.",
|
|
104
|
+
schema: z.object({
|
|
105
|
+
calls: z.array(
|
|
106
|
+
z.object({
|
|
107
|
+
target: addressSchema.describe(
|
|
108
|
+
"Target contract address (0x-prefixed 20-byte hex)"
|
|
109
|
+
),
|
|
110
|
+
value: weiValueSchema.optional().describe("ETH value in wei (as string). Defaults to '0'."),
|
|
111
|
+
data: z.string().optional().describe("Calldata (0x-prefixed hex). Defaults to '0x'.")
|
|
112
|
+
})
|
|
113
|
+
).min(1).describe("Array of calls to execute atomically")
|
|
114
|
+
}),
|
|
115
|
+
func: async ({ calls }) => {
|
|
116
|
+
try {
|
|
117
|
+
const wallet = {
|
|
118
|
+
address,
|
|
119
|
+
owner: address,
|
|
120
|
+
chain: {},
|
|
121
|
+
isDeployed: true,
|
|
122
|
+
policies: [],
|
|
123
|
+
sessions: []
|
|
124
|
+
};
|
|
125
|
+
const txHash = await client.executeBatch(wallet, {
|
|
126
|
+
calls: calls.map((c) => ({
|
|
127
|
+
target: c.target,
|
|
128
|
+
value: c.value ? BigInt(c.value) : 0n,
|
|
129
|
+
data: c.data ?? "0x"
|
|
130
|
+
})),
|
|
131
|
+
sessionKey
|
|
132
|
+
});
|
|
133
|
+
return JSON.stringify({
|
|
134
|
+
success: true,
|
|
135
|
+
transactionHash: txHash,
|
|
136
|
+
callCount: calls.length
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
return JSON.stringify({
|
|
140
|
+
success: false,
|
|
141
|
+
error: error instanceof Error ? error.message : String(error)
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
const checkWalletStatus = new DynamicStructuredTool({
|
|
147
|
+
name: "check_wallet_status",
|
|
148
|
+
description: "Check if the agent's smart wallet is currently paused. A paused wallet cannot execute any transactions. The guardian can pause the wallet in emergencies.",
|
|
149
|
+
schema: z.object({}),
|
|
150
|
+
func: async () => {
|
|
151
|
+
try {
|
|
152
|
+
const paused = await client.isPaused(address);
|
|
153
|
+
return JSON.stringify({
|
|
154
|
+
wallet: walletAddress,
|
|
155
|
+
paused,
|
|
156
|
+
status: paused ? "paused" : "active"
|
|
157
|
+
});
|
|
158
|
+
} catch (error) {
|
|
159
|
+
return JSON.stringify({
|
|
160
|
+
error: error instanceof Error ? error.message : String(error)
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return [
|
|
166
|
+
checkWalletBalance,
|
|
167
|
+
checkSpendingAllowance,
|
|
168
|
+
sendTransaction,
|
|
169
|
+
sendBatchTransaction,
|
|
170
|
+
checkWalletStatus
|
|
171
|
+
];
|
|
172
|
+
}
|
|
173
|
+
export {
|
|
174
|
+
createSmartAgentKitTools
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools.ts"],"sourcesContent":["import { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport type { ISmartAgentKitClient } from \"@smartagentkit/sdk\";\n\n// Reusable Zod pattern for 0x-prefixed Ethereum addresses (20 bytes)\nconst addressSchema = z\n .string()\n .regex(/^0x[0-9a-fA-F]{40}$/, \"Must be a 0x-prefixed 20-byte hex address\");\n\n// Reusable Zod pattern for non-negative integer strings (wei values)\nconst weiValueSchema = z\n .string()\n .regex(/^\\d+$/, \"Must be a non-negative integer string (wei)\");\n\n// Reusable Zod pattern for 0x-prefixed hex calldata (even-length)\nconst calldataSchema = z\n .string()\n .regex(/^0x([0-9a-fA-F]{2})*$/, \"Must be 0x-prefixed hex calldata (even length)\");\n\n/**\n * Creates LangChain tools for interacting with a SmartAgentKit wallet.\n *\n * Returns 5 tools that an LLM agent can use to manage and transact\n * from a policy-governed smart wallet:\n *\n * - **check_wallet_balance** — Get ETH balance\n * - **check_spending_allowance** — Query remaining spending limit for a token\n * - **send_transaction** — Execute an on-chain transaction\n * - **send_batch_transaction** — Execute multiple calls atomically\n * - **check_wallet_status** — Check if wallet is paused\n *\n * @param client - An initialized SmartAgentKitClient\n * @param walletAddress - The smart wallet address to operate on\n * @param sessionKey - Optional session key private key for signing transactions\n * @returns Array of DynamicStructuredTool instances for use with LangChain agents\n *\n * @example\n * ```ts\n * import { createSmartAgentKitTools } from \"@smartagentkit/langchain\";\n * import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n *\n * const tools = createSmartAgentKitTools(client, wallet.address, sessionKey);\n * const agent = createReactAgent({ llm: chatModel, tools });\n * ```\n */\nexport function createSmartAgentKitTools(\n client: ISmartAgentKitClient,\n walletAddress: string,\n sessionKey?: string,\n): DynamicStructuredTool[] {\n const address = walletAddress as `0x${string}`;\n\n // ─── check_wallet_balance ─────────────────────────────────────\n\n const checkWalletBalance = new DynamicStructuredTool({\n name: \"check_wallet_balance\",\n description:\n \"Check the ETH balance of the agent's smart wallet. \" +\n \"Returns the balance in ETH (assuming 18 decimals). \" +\n \"The raw wei value is also returned for precision. \" +\n \"Use this before sending transactions to ensure sufficient funds.\",\n schema: z.object({}),\n func: async () => {\n try {\n const balances = await client.getBalances(address);\n // Note: Division by 1e18 assumes 18 decimals (correct for native ETH).\n // For ERC-20 tokens, use the raw wei value and the token's actual decimals.\n const ethBalance = Number(balances.eth) / 1e18;\n return JSON.stringify({\n wallet: walletAddress,\n eth: ethBalance.toString(),\n ethWei: balances.eth.toString(),\n });\n } catch (error) {\n return JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── check_spending_allowance ────────────────────────────────\n\n const checkSpendingAllowance = new DynamicStructuredTool({\n name: \"check_spending_allowance\",\n description:\n \"Check how much spending allowance remains for a token on the wallet. \" +\n \"The wallet has policy-enforced spending limits per token per time window. \" +\n \"Use this to verify you can spend a certain amount before sending a transaction. \" +\n 'Use \"0x0000000000000000000000000000000000000000\" for native ETH.',\n schema: z.object({\n token: addressSchema.describe(\n \"Token contract address. Use 0x0000000000000000000000000000000000000000 for native ETH.\",\n ),\n }),\n func: async ({ token }) => {\n try {\n const remaining = await client.getRemainingAllowance(\n address,\n token as `0x${string}`,\n );\n // Note: Division by 1e18 assumes 18 decimals (correct for native ETH).\n // For tokens with different decimals (e.g., USDC = 6), use remainingWei\n // and divide by the token's actual decimal factor.\n const remainingEth = Number(remaining) / 1e18;\n return JSON.stringify({\n wallet: walletAddress,\n token,\n remainingWei: remaining.toString(),\n remaining: remainingEth.toString(),\n });\n } catch (error) {\n return JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── send_transaction ─────────────────────────────────────────\n\n const sendTransaction = new DynamicStructuredTool({\n name: \"send_transaction\",\n description:\n \"Send a transaction from the agent's smart wallet. \" +\n \"The transaction is executed as a UserOperation through ERC-4337 \" +\n \"and is subject to the wallet's policy constraints (spending limits, \" +\n \"allowlist, pause state). All values are in wei (1 ETH = 1e18 wei). \" +\n \"Returns the transaction hash on success.\",\n schema: z.object({\n target: addressSchema.describe(\n \"Target contract address to call (0x-prefixed 20-byte hex)\",\n ),\n value: weiValueSchema\n .optional()\n .describe(\n \"ETH value to send in wei (as string). Defaults to '0'. Example: '1000000000000000' for 0.001 ETH.\",\n ),\n data: calldataSchema\n .optional()\n .describe(\n \"Calldata for the transaction (0x-prefixed hex). Defaults to '0x' for simple ETH transfer.\",\n ),\n }),\n func: async ({ target, value, data }) => {\n try {\n const wallet = {\n address,\n owner: address, // Resolved from connected wallet\n chain: {} as never, // Not used in execute\n isDeployed: true,\n policies: [],\n sessions: [],\n };\n\n const txHash = await client.execute(wallet, {\n target: target as `0x${string}`,\n value: value ? BigInt(value) : 0n,\n data: (data as `0x${string}`) ?? \"0x\",\n sessionKey: sessionKey as `0x${string}` | undefined,\n });\n\n return JSON.stringify({\n success: true,\n transactionHash: txHash,\n });\n } catch (error) {\n return JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── send_batch_transaction ───────────────────────────────────\n\n const sendBatchTransaction = new DynamicStructuredTool({\n name: \"send_batch_transaction\",\n description:\n \"Send multiple transactions atomically from the agent's smart wallet. \" +\n \"All calls are bundled into a single UserOperation and either all succeed or all revert. \" +\n \"Useful for approve+swap, multi-transfer, or any multi-step operation. \" +\n \"Subject to the wallet's policy constraints. All values are in wei.\",\n schema: z.object({\n calls: z\n .array(\n z.object({\n target: addressSchema.describe(\n \"Target contract address (0x-prefixed 20-byte hex)\",\n ),\n value: weiValueSchema\n .optional()\n .describe(\"ETH value in wei (as string). Defaults to '0'.\"),\n data: z\n .string()\n .optional()\n .describe(\"Calldata (0x-prefixed hex). Defaults to '0x'.\"),\n }),\n )\n .min(1)\n .describe(\"Array of calls to execute atomically\"),\n }),\n func: async ({ calls }) => {\n try {\n const wallet = {\n address,\n owner: address,\n chain: {} as never,\n isDeployed: true,\n policies: [],\n sessions: [],\n };\n\n const txHash = await client.executeBatch(wallet, {\n calls: calls.map((c) => ({\n target: c.target as `0x${string}`,\n value: c.value ? BigInt(c.value) : 0n,\n data: (c.data as `0x${string}`) ?? \"0x\",\n })),\n sessionKey: sessionKey as `0x${string}` | undefined,\n });\n\n return JSON.stringify({\n success: true,\n transactionHash: txHash,\n callCount: calls.length,\n });\n } catch (error) {\n return JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n // ─── check_wallet_status ─────────────────────────────────────\n\n const checkWalletStatus = new DynamicStructuredTool({\n name: \"check_wallet_status\",\n description:\n \"Check if the agent's smart wallet is currently paused. \" +\n \"A paused wallet cannot execute any transactions. \" +\n \"The guardian can pause the wallet in emergencies.\",\n schema: z.object({}),\n func: async () => {\n try {\n const paused = await client.isPaused(address);\n return JSON.stringify({\n wallet: walletAddress,\n paused,\n status: paused ? \"paused\" : \"active\",\n });\n } catch (error) {\n return JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n });\n }\n },\n });\n\n return [\n checkWalletBalance,\n checkSpendingAllowance,\n sendTransaction,\n sendBatchTransaction,\n checkWalletStatus,\n ];\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@smartagentkit/langchain",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "LangChain integration for SmartAgentKit — AI agent smart wallet tools",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "SmartAgentKit Contributors",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/smartagentkit/smartagentkit.git",
|
|
10
|
+
"directory": "packages/integrations/langchain"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/smartagentkit/smartagentkit#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/smartagentkit/smartagentkit/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"smart-wallet",
|
|
18
|
+
"ai-agent",
|
|
19
|
+
"langchain",
|
|
20
|
+
"erc4337",
|
|
21
|
+
"account-abstraction",
|
|
22
|
+
"policy",
|
|
23
|
+
"ethereum",
|
|
24
|
+
"defi"
|
|
25
|
+
],
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.mjs",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.mjs",
|
|
33
|
+
"require": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist"
|
|
38
|
+
],
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"zod": "^3.24.0",
|
|
44
|
+
"@smartagentkit/sdk": "0.1.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@langchain/core": ">=0.3.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@langchain/core": "^0.3.0",
|
|
51
|
+
"tsup": "^8.4.0",
|
|
52
|
+
"vitest": "^3.0.0",
|
|
53
|
+
"typescript": "^5.7.0"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsup",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"lint": "tsc --noEmit",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"clean": "rm -rf dist"
|
|
61
|
+
}
|
|
62
|
+
}
|