hybrid 1.2.4 → 1.2.6

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/README.md CHANGED
@@ -1,167 +1,66 @@
1
- # Hybrid Agent Framework
2
-
3
- A flexible framework for building AI agents with plugin-based HTTP server extensions.
4
-
5
- ## Features
6
-
7
- - **AI Agent Core**: Built on AI SDK 5 with streaming and tool support
8
- - **Plugin System**: Extensible HTTP server with Hono integration
9
- - **XMTP Integration**: Built-in XMTP messaging capabilities
10
- - **Blockchain Events**: Ponder integration for blockchain event handling
11
- - **TypeScript First**: Full type safety and modern TypeScript patterns
12
-
13
- ## Quick Start
14
-
15
- ```typescript
16
- import { Agent, XMTPPlugin, PonderPlugin } from "hybrid"
17
-
18
- // Create an agent
19
- const agent = new Agent({
20
- name: "my-agent",
21
- model: "gpt-4",
22
- instructions: "You are a helpful AI assistant."
23
- })
24
-
25
- // Start the server with plugins
26
- await agent.listen({
27
- port: "3000",
28
- filter: async ({ message }) => {
29
- console.log("Received message:", message)
30
- return true // Accept all messages
31
- },
32
- plugins: [
33
- XMTPPlugin(),
34
- PonderPlugin()
35
- ]
36
- })
37
- ```
38
-
39
- ## Plugin System
40
-
41
- The framework uses a plugin-based architecture that allows you to extend the agent's HTTP server with additional functionality.
42
-
43
- ### Built-in Plugins
44
-
45
- - **XMTPPlugin**: Provides XMTP messaging capabilities
46
- - **PonderPlugin**: Handles blockchain events via Ponder
47
-
48
- ### Creating Custom Plugins
49
-
50
- ```typescript
51
- import type { Plugin } from "hybrid"
52
- import { Hono } from "hono"
53
-
54
- function MyCustomPlugin(): Plugin {
55
- return {
56
- name: "my-custom",
57
- description: "My custom functionality",
58
- apply: (app) => {
59
- app.get("/custom", (c) => c.json({ message: "Hello from custom plugin!" }))
60
- }
61
- }
62
- }
63
-
64
- // Use the plugin
65
- const agent = new Agent({
66
- name: "my-agent",
67
- model: "gpt-4",
68
- instructions: "You are a helpful AI assistant."
69
- })
70
-
71
- // Start server with plugins
72
- await agent.listen({
73
- port: "3000",
74
- plugins: [
75
- XMTPPlugin(),
76
- PonderPlugin(),
77
- MyCustomPlugin()
78
- ]
79
- })
80
- ```
1
+ # Hybrid - Typescript Framework for building commerce-connected AI Agents.
81
2
 
82
- ### Plugin Registry
3
+ An open-source agent framework for building conversational AI agents on XMTP.
83
4
 
84
- You can also register plugins dynamically:
5
+ Hybrid makes it easy for developers to create intelligent agents that can understand natural language, process messages, and respond through XMTP's decentralized messaging protocol.
85
6
 
86
- ```typescript
87
- // Register a plugin after agent creation
88
- agent.use(MyCustomPlugin())
7
+ See [http://hybriddev.com](http://hybrid.dev) for more information.
89
8
 
90
- // Check registered plugins
91
- console.log(`Agent has ${agent.plugins.size} plugins`)
9
+ ## đŸ“Ļ Quickstart
92
10
 
93
- // Get a specific plugin
94
- const plugin = agent.plugins.get("my-custom")
11
+ Getting started with Hybrid is simple:
95
12
 
96
- // Check if a plugin is registered
97
- if (agent.plugins.has("xmtp")) {
98
- console.log("XMTP plugin is registered")
99
- }
100
- ```
13
+ ### 1. Initialize your project
101
14
 
102
- ### Plugin Context
103
-
104
- Plugins receive a context object with the agent instance:
105
-
106
- ```typescript
107
- function MyPlugin(): Plugin {
108
- return {
109
- name: "my-plugin",
110
- description: "My plugin",
111
- apply: (app, context) => {
112
- if (context) {
113
- console.log(`Plugin applied to agent: ${context.agent.name}`)
114
- }
115
-
116
- app.get("/my-endpoint", (c) => c.json({ message: "Hello!" }))
117
- }
118
- }
119
- }
15
+ ```bash
16
+ npm create hybrid my-agent
17
+ cd my-agent
120
18
  ```
121
19
 
122
- ## Architecture
20
+ This creates all the necessary files and configuration for your agent.
123
21
 
124
- The framework consists of several core components:
22
+ ### 2. Get your OpenRouter API key
23
+
24
+ Visit [OpenRouter](https://openrouter.ai/keys), create an account and generate an API key
125
25
 
126
- - **Agent**: Main AI agent with streaming and tool support
127
- - **Plugin System**: Extensible HTTP server architecture with Hono
128
- - **Tool System**: AI SDK compatible tool framework
129
- - **Server**: Hono-based HTTP server with plugin support
26
+ Add it to your `.env` file:
130
27
 
131
- ### Plugin Lifecycle
28
+ ```env
29
+ OPENROUTER_API_KEY=your_openrouter_api_key_here
30
+ ```
132
31
 
133
- 1. **Registration**: Plugins are registered during agent creation or via `agent.use()`
134
- 2. **Application**: When `agent.listen()` is called, all plugins are applied to the Hono app
135
- 3. **Execution**: Plugins can add routes, middleware, and other functionality to the app
32
+ ### 3. Generate XMTP keys
136
33
 
137
- ## Examples
34
+ ```bash
35
+ hybrid keys
36
+ ```
138
37
 
139
- See the `examples/` directory for complete usage examples:
38
+ or automatically add it to your `.env` file:
140
39
 
141
- - `plugin-usage.ts`: Comprehensive plugin usage examples
142
- - Basic plugin registration
143
- - Dynamic plugin registration
144
- - Custom plugin creation
145
- - Plugin registry inspection
146
- - Server startup with plugins
40
+ ```bash
41
+ hybrid keys --write
42
+ ```
147
43
 
148
- ## Development
44
+ ### 4. Register your wallet with XMTP
149
45
 
150
46
  ```bash
151
- # Install dependencies
152
- pnpm install
47
+ hybrid register
48
+ ```
153
49
 
154
- # Build the package
155
- pnpm build
50
+ This generates secure wallet and encryption keys for your XMTP agent.
156
51
 
157
- # Run tests
158
- pnpm test
52
+ ### 5. Register your wallet with XMTP
159
53
 
160
- # Type check
161
- pnpm typecheck
54
+ ```bash
55
+ hybrid register
162
56
  ```
163
57
 
164
- ## License
58
+ ### 6. Start developing
59
+
60
+ ```bash
61
+ hybrid dev
62
+ ```
165
63
 
166
- MIT
64
+ Your agent will start listening for XMTP messages and you're ready to build!
167
65
 
66
+ Go to [https://xmtp.chat/dm/](https://xmtp.chat/dm/) and send a message to your agent.
package/README.md.old ADDED
@@ -0,0 +1,167 @@
1
+ # Hybrid Agent Framework
2
+
3
+ A flexible framework for building AI agents with plugin-based HTTP server extensions.
4
+
5
+ ## Features
6
+
7
+ - **AI Agent Core**: Built on AI SDK 5 with streaming and tool support
8
+ - **Plugin System**: Extensible HTTP server with Hono integration
9
+ - **XMTP Integration**: Built-in XMTP messaging capabilities
10
+ - **Blockchain Events**: Ponder integration for blockchain event handling
11
+ - **TypeScript First**: Full type safety and modern TypeScript patterns
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { Agent, XMTPPlugin, PonderPlugin } from "hybrid"
17
+
18
+ // Create an agent
19
+ const agent = new Agent({
20
+ name: "my-agent",
21
+ model: "gpt-4",
22
+ instructions: "You are a helpful AI assistant."
23
+ })
24
+
25
+ // Start the server with plugins
26
+ await agent.listen({
27
+ port: "3000",
28
+ filter: async ({ message }) => {
29
+ console.log("Received message:", message)
30
+ return true // Accept all messages
31
+ },
32
+ plugins: [
33
+ XMTPPlugin(),
34
+ PonderPlugin()
35
+ ]
36
+ })
37
+ ```
38
+
39
+ ## Plugin System
40
+
41
+ The framework uses a plugin-based architecture that allows you to extend the agent's HTTP server with additional functionality.
42
+
43
+ ### Built-in Plugins
44
+
45
+ - **XMTPPlugin**: Provides XMTP messaging capabilities
46
+ - **PonderPlugin**: Handles blockchain events via Ponder
47
+
48
+ ### Creating Custom Plugins
49
+
50
+ ```typescript
51
+ import type { Plugin } from "hybrid"
52
+ import { Hono } from "hono"
53
+
54
+ function MyCustomPlugin(): Plugin {
55
+ return {
56
+ name: "my-custom",
57
+ description: "My custom functionality",
58
+ apply: (app) => {
59
+ app.get("/custom", (c) => c.json({ message: "Hello from custom plugin!" }))
60
+ }
61
+ }
62
+ }
63
+
64
+ // Use the plugin
65
+ const agent = new Agent({
66
+ name: "my-agent",
67
+ model: "gpt-4",
68
+ instructions: "You are a helpful AI assistant."
69
+ })
70
+
71
+ // Start server with plugins
72
+ await agent.listen({
73
+ port: "3000",
74
+ plugins: [
75
+ XMTPPlugin(),
76
+ PonderPlugin(),
77
+ MyCustomPlugin()
78
+ ]
79
+ })
80
+ ```
81
+
82
+ ### Plugin Registry
83
+
84
+ You can also register plugins dynamically:
85
+
86
+ ```typescript
87
+ // Register a plugin after agent creation
88
+ agent.use(MyCustomPlugin())
89
+
90
+ // Check registered plugins
91
+ console.log(`Agent has ${agent.plugins.size} plugins`)
92
+
93
+ // Get a specific plugin
94
+ const plugin = agent.plugins.get("my-custom")
95
+
96
+ // Check if a plugin is registered
97
+ if (agent.plugins.has("xmtp")) {
98
+ console.log("XMTP plugin is registered")
99
+ }
100
+ ```
101
+
102
+ ### Plugin Context
103
+
104
+ Plugins receive a context object with the agent instance:
105
+
106
+ ```typescript
107
+ function MyPlugin(): Plugin {
108
+ return {
109
+ name: "my-plugin",
110
+ description: "My plugin",
111
+ apply: (app, context) => {
112
+ if (context) {
113
+ console.log(`Plugin applied to agent: ${context.agent.name}`)
114
+ }
115
+
116
+ app.get("/my-endpoint", (c) => c.json({ message: "Hello!" }))
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ ## Architecture
123
+
124
+ The framework consists of several core components:
125
+
126
+ - **Agent**: Main AI agent with streaming and tool support
127
+ - **Plugin System**: Extensible HTTP server architecture with Hono
128
+ - **Tool System**: AI SDK compatible tool framework
129
+ - **Server**: Hono-based HTTP server with plugin support
130
+
131
+ ### Plugin Lifecycle
132
+
133
+ 1. **Registration**: Plugins are registered during agent creation or via `agent.use()`
134
+ 2. **Application**: When `agent.listen()` is called, all plugins are applied to the Hono app
135
+ 3. **Execution**: Plugins can add routes, middleware, and other functionality to the app
136
+
137
+ ## Examples
138
+
139
+ See the `examples/` directory for complete usage examples:
140
+
141
+ - `plugin-usage.ts`: Comprehensive plugin usage examples
142
+ - Basic plugin registration
143
+ - Dynamic plugin registration
144
+ - Custom plugin creation
145
+ - Plugin registry inspection
146
+ - Server startup with plugins
147
+
148
+ ## Development
149
+
150
+ ```bash
151
+ # Install dependencies
152
+ pnpm install
153
+
154
+ # Build the package
155
+ pnpm build
156
+
157
+ # Run tests
158
+ pnpm test
159
+
160
+ # Type check
161
+ pnpm typecheck
162
+ ```
163
+
164
+ ## License
165
+
166
+ MIT
167
+
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tools/index.ts","../../src/tools/blockchain.ts","../../src/core/tool.ts","../../src/tools/xmtp.ts"],"sourcesContent":["/**\n * @fileoverview Hybrid Agent Tools Standard Library\n *\n * This module provides a comprehensive set of tools for building crypto-enabled agents.\n * Tools are organized by category and can be imported individually or as complete sets.\n *\n * @example\n * ```typescript\n * import { blockchainTools, xmtpTools } from \"hybrid/tools\"\n * import { Agent } from \"hybrid\"\n *\n * const agent = new Agent({\n * name: \"crypto-agent\",\n * model: myModel,\n * tools: {\n * ...blockchainTools,\n * ...xmtpTools\n * },\n * instructions: \"You are a crypto agent with blockchain and messaging capabilities.\",\n * createRuntime: (runtime) => ({\n * rpcUrl: process.env.RPC_URL,\n * privateKey: process.env.PRIVATE_KEY,\n * defaultChain: \"mainnet\" as const\n * })\n * })\n * ```\n *\n * @module HybridTools\n */\n\n// Export blockchain tools\nexport {\n\tblockchainTools,\n\testimateGasTool,\n\tgetBalanceTool,\n\tgetBlockTool,\n\tgetGasPriceTool,\n\tgetTransactionTool,\n\tsendTransactionTool,\n\ttype BlockchainRuntimeExtension\n} from \"./blockchain\"\n\n// Export XMTP tools\nexport {\n\tgetMessageTool,\n\tsendMessageTool,\n\tsendReactionTool,\n\tsendReplyTool,\n\txmtpTools\n} from \"./xmtp\"\n","/**\n * @fileoverview Blockchain Tools for Crypto Agents\n *\n * This module provides comprehensive blockchain interaction tools for crypto-enabled agents.\n * Supports Ethereum and other EVM-compatible chains with features like balance checking,\n * transaction sending, contract interaction, and more.\n *\n * @module BlockchainTools\n */\n\nimport {\n\tcreatePublicClient,\n\tcreateWalletClient,\n\tformatEther,\n\thttp,\n\tparseEther,\n\ttype Address,\n\ttype Hash\n} from \"viem\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport {\n\tarbitrum,\n\tbase,\n\tmainnet,\n\toptimism,\n\tpolygon,\n\tsepolia\n} from \"viem/chains\"\nimport { z } from \"zod\"\nimport { createTool } from \"../core/tool\"\n\n// Supported chains configuration\nconst SUPPORTED_CHAINS = {\n\tmainnet,\n\tsepolia,\n\tpolygon,\n\tarbitrum,\n\toptimism,\n\tbase\n} as const\n\ntype SupportedChain = keyof typeof SUPPORTED_CHAINS\n\n// Runtime extension interface for blockchain tools\nexport interface BlockchainRuntimeExtension {\n\trpcUrl?: string\n\tprivateKey?: string\n\tdefaultChain?: SupportedChain\n}\n\n/**\n * Get Balance Tool\n *\n * Retrieves the native token balance for a given address on a specified chain.\n *\n * @tool getBalance\n * @category Blockchain\n *\n * @param {string} address - The wallet address to check balance for\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, balance: string, balanceWei: string, address: string, chain: string, error?: string}>}\n */\nexport const getBalanceTool = createTool({\n\tid: \"getBalance\",\n\tdescription:\n\t\t\"Get the native token balance for a wallet address on a blockchain\",\n\tinputSchema: z.object({\n\t\taddress: z.string().describe(\"The wallet address to check balance for\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tbalance: z\n\t\t\t.string()\n\t\t\t.describe(\"Balance in human readable format (ETH, MATIC, etc.)\"),\n\t\tbalanceWei: z.string().describe(\"Balance in wei (smallest unit)\"),\n\t\taddress: z.string(),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { address, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\t// Use runtime RPC URL if provided, otherwise use default\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(`🔍 [getBalance] Checking balance for ${address} on ${chain}`)\n\n\t\t\tconst balanceWei = await client.getBalance({\n\t\t\t\taddress: address as Address\n\t\t\t})\n\n\t\t\tconst balance = formatEther(balanceWei)\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getBalance] Balance: ${balance} ${chainConfig.nativeCurrency.symbol}`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tbalance: `${balance} ${chainConfig.nativeCurrency.symbol}`,\n\t\t\t\tbalanceWei: balanceWei.toString(),\n\t\t\t\taddress,\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getBalance] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tbalance: \"0\",\n\t\t\t\tbalanceWei: \"0\",\n\t\t\t\taddress: input.address,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Transaction Tool\n *\n * Retrieves transaction details by transaction hash.\n *\n * @tool getTransaction\n * @category Blockchain\n *\n * @param {string} hash - The transaction hash to look up\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, transaction?: object, error?: string}>}\n */\nexport const getTransactionTool = createTool({\n\tid: \"getTransaction\",\n\tdescription: \"Get transaction details by transaction hash\",\n\tinputSchema: z.object({\n\t\thash: z.string().describe(\"The transaction hash to look up\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\ttransaction: z\n\t\t\t.object({\n\t\t\t\thash: z.string(),\n\t\t\t\tfrom: z.string(),\n\t\t\t\tto: z.string().nullable(),\n\t\t\t\tvalue: z.string(),\n\t\t\t\tgasUsed: z.string().optional(),\n\t\t\t\tgasPrice: z.string().optional(),\n\t\t\t\tblockNumber: z.string().optional(),\n\t\t\t\tstatus: z.string().optional()\n\t\t\t})\n\t\t\t.optional(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { hash, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`🔍 [getTransaction] Looking up transaction ${hash} on ${chain}`\n\t\t\t)\n\n\t\t\tconst transaction = await client.getTransaction({\n\t\t\t\thash: hash as Hash\n\t\t\t})\n\n\t\t\tconst receipt = await client\n\t\t\t\t.getTransactionReceipt({\n\t\t\t\t\thash: hash as Hash\n\t\t\t\t})\n\t\t\t\t.catch(() => null) // Transaction might be pending\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getTransaction] Found transaction from ${transaction.from} to ${transaction.to}`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\ttransaction: {\n\t\t\t\t\thash: transaction.hash,\n\t\t\t\t\tfrom: transaction.from,\n\t\t\t\t\tto: transaction.to,\n\t\t\t\t\tvalue: formatEther(transaction.value),\n\t\t\t\t\tgasUsed: receipt?.gasUsed.toString(),\n\t\t\t\t\tgasPrice: transaction.gasPrice?.toString(),\n\t\t\t\t\tblockNumber: transaction.blockNumber?.toString(),\n\t\t\t\t\tstatus:\n\t\t\t\t\t\treceipt?.status === \"success\"\n\t\t\t\t\t\t\t? \"success\"\n\t\t\t\t\t\t\t: receipt?.status === \"reverted\"\n\t\t\t\t\t\t\t\t? \"failed\"\n\t\t\t\t\t\t\t\t: \"pending\"\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getTransaction] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Send Transaction Tool\n *\n * Sends a native token transaction to another address.\n * Requires a private key to be configured in the runtime.\n *\n * @tool sendTransaction\n * @category Blockchain\n *\n * @param {string} to - The recipient address\n * @param {string} amount - The amount to send (in ETH, MATIC, etc.)\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, hash?: string, error?: string}>}\n */\nexport const sendTransactionTool = createTool({\n\tid: \"sendTransaction\",\n\tdescription: \"Send native tokens to another address\",\n\tinputSchema: z.object({\n\t\tto: z.string().describe(\"The recipient address\"),\n\t\tamount: z.string().describe(\"The amount to send (in ETH, MATIC, etc.)\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to send on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\thash: z.string().optional(),\n\t\tfrom: z.string().optional(),\n\t\tto: z.string(),\n\t\tamount: z.string(),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { to, amount, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst privateKey = (runtime as any).privateKey\n\t\t\tif (!privateKey) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tto,\n\t\t\t\t\tamount,\n\t\t\t\t\tchain,\n\t\t\t\t\terror: \"Private key not configured in runtime\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\t\t\tconst account = privateKeyToAccount(privateKey as `0x${string}`)\n\n\t\t\tconst client = createWalletClient({\n\t\t\t\taccount,\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`💸 [sendTransaction] Sending ${amount} ${chainConfig.nativeCurrency.symbol} to ${to} on ${chain}`\n\t\t\t)\n\n\t\t\tconst hash = await client.sendTransaction({\n\t\t\t\tto: to as Address,\n\t\t\t\tvalue: parseEther(amount)\n\t\t\t})\n\n\t\t\tconsole.log(`✅ [sendTransaction] Transaction sent: ${hash}`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\thash,\n\t\t\t\tfrom: account.address,\n\t\t\t\tto,\n\t\t\t\tamount,\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendTransaction] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tto: input.to,\n\t\t\t\tamount: input.amount,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Block Tool\n *\n * Retrieves information about a specific block.\n *\n * @tool getBlock\n * @category Blockchain\n *\n * @param {string} [blockNumber] - Block number (defaults to latest)\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, block?: object, error?: string}>}\n */\nexport const getBlockTool = createTool({\n\tid: \"getBlock\",\n\tdescription: \"Get information about a blockchain block\",\n\tinputSchema: z.object({\n\t\tblockNumber: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Block number (defaults to latest)\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tblock: z\n\t\t\t.object({\n\t\t\t\tnumber: z.string(),\n\t\t\t\thash: z.string(),\n\t\t\t\ttimestamp: z.string(),\n\t\t\t\ttransactionCount: z.number(),\n\t\t\t\tgasUsed: z.string(),\n\t\t\t\tgasLimit: z.string()\n\t\t\t})\n\t\t\t.optional(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { blockNumber, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`🔍 [getBlock] Getting block ${blockNumber || \"latest\"} on ${chain}`\n\t\t\t)\n\n\t\t\tconst block = await client.getBlock({\n\t\t\t\tblockNumber: blockNumber ? BigInt(blockNumber) : undefined\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getBlock] Found block ${block.number} with ${block.transactions.length} transactions`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tblock: {\n\t\t\t\t\tnumber: block.number.toString(),\n\t\t\t\t\thash: block.hash,\n\t\t\t\t\ttimestamp: block.timestamp.toString(),\n\t\t\t\t\ttransactionCount: block.transactions.length,\n\t\t\t\t\tgasUsed: block.gasUsed.toString(),\n\t\t\t\t\tgasLimit: block.gasLimit.toString()\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getBlock] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Gas Price Tool\n *\n * Retrieves current gas price information for a blockchain.\n *\n * @tool getGasPrice\n * @category Blockchain\n *\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, gasPrice?: string, error?: string}>}\n */\nexport const getGasPriceTool = createTool({\n\tid: \"getGasPrice\",\n\tdescription: \"Get current gas price for a blockchain\",\n\tinputSchema: z.object({\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tgasPrice: z.string().optional().describe(\"Gas price in gwei\"),\n\t\tgasPriceWei: z.string().optional().describe(\"Gas price in wei\"),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(`â›Ŋ [getGasPrice] Getting gas price for ${chain}`)\n\n\t\t\tconst gasPrice = await client.getGasPrice()\n\t\t\tconst gasPriceGwei = formatEther(gasPrice * BigInt(1000000000)) // Convert to gwei\n\n\t\t\tconsole.log(`✅ [getGasPrice] Current gas price: ${gasPriceGwei} gwei`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tgasPrice: `${gasPriceGwei} gwei`,\n\t\t\t\tgasPriceWei: gasPrice.toString(),\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getGasPrice] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Estimate Gas Tool\n *\n * Estimates gas required for a transaction.\n *\n * @tool estimateGas\n * @category Blockchain\n *\n * @param {string} to - The recipient address\n * @param {string} [amount] - The amount to send (defaults to 0)\n * @param {string} [data] - Transaction data (for contract calls)\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, gasEstimate?: string, error?: string}>}\n */\nexport const estimateGasTool = createTool({\n\tid: \"estimateGas\",\n\tdescription: \"Estimate gas required for a transaction\",\n\tinputSchema: z.object({\n\t\tto: z.string().describe(\"The recipient address\"),\n\t\tamount: z\n\t\t\t.string()\n\t\t\t.default(\"0\")\n\t\t\t.describe(\"The amount to send (defaults to 0)\"),\n\t\tdata: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Transaction data (for contract calls)\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to estimate on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tgasEstimate: z.string().optional(),\n\t\tto: z.string(),\n\t\tamount: z.string(),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { to, amount, data, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst privateKey = (runtime as any).privateKey\n\t\t\tif (!privateKey) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tto,\n\t\t\t\t\tamount,\n\t\t\t\t\tchain,\n\t\t\t\t\terror: \"Private key not configured in runtime\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\t\t\tconst account = privateKeyToAccount(privateKey as `0x${string}`)\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`â›Ŋ [estimateGas] Estimating gas for transaction to ${to} on ${chain}`\n\t\t\t)\n\n\t\t\tconst gasEstimate = await client.estimateGas({\n\t\t\t\taccount: account.address,\n\t\t\t\tto: to as Address,\n\t\t\t\tvalue: parseEther(amount),\n\t\t\t\tdata: data as `0x${string}` | undefined\n\t\t\t})\n\n\t\t\tconsole.log(`✅ [estimateGas] Estimated gas: ${gasEstimate.toString()}`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tgasEstimate: gasEstimate.toString(),\n\t\t\t\tto,\n\t\t\t\tamount,\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [estimateGas] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tto: input.to,\n\t\t\t\tamount: input.amount,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Collection of blockchain tools for crypto agents\n *\n * These tools provide comprehensive blockchain interaction capabilities including\n * balance checking, transaction sending, gas estimation, and more.\n *\n * @namespace blockchainTools\n *\n * @property {Tool} getBalance - Get native token balance for an address\n * @property {Tool} getTransaction - Get transaction details by hash\n * @property {Tool} sendTransaction - Send native tokens to another address\n * @property {Tool} getBlock - Get information about a blockchain block\n * @property {Tool} getGasPrice - Get current gas price for a blockchain\n * @property {Tool} estimateGas - Estimate gas required for a transaction\n */\nexport const blockchainTools = {\n\tgetBalance: getBalanceTool,\n\tgetTransaction: getTransactionTool,\n\tsendTransaction: sendTransactionTool,\n\tgetBlock: getBlockTool,\n\tgetGasPrice: getGasPriceTool,\n\testimateGas: estimateGasTool\n}\n","import { Tool as AISDKTool, type UIMessage } from \"ai\"\nimport { z } from \"zod\"\nimport { AgentRuntime } from \"../types\"\n\ntype DefaultRuntimeExtension = Record<string, never>\n\n/**\n * Configuration interface for creating custom tools that integrate with AI SDK.\n */\nexport interface ToolConfig<\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTRuntimeExtension = DefaultRuntimeExtension\n> {\n\t/** Unique identifier for the tool */\n\tid: string\n\t/** Human-readable description of what the tool does */\n\tdescription: string\n\t/** Zod schema for validating tool input */\n\tinputSchema: TInput\n\t/** Optional Zod schema for validating tool output */\n\toutputSchema?: TOutput\n\t/** Function that executes the tool's logic */\n\texecute: (args: {\n\t\tinput: z.infer<TInput>\n\t\truntime: AgentRuntime & TRuntimeExtension\n\t\tmessages: UIMessage[]\n\t}) => Promise<z.infer<TOutput>>\n}\n\n/**\n * Internal tool interface used throughout the agent framework.\n * Similar to ToolConfig but without the ID field, used after tool creation.\n */\nexport interface Tool<\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTRuntimeExtension = DefaultRuntimeExtension\n> {\n\t/** Human-readable description of what the tool does */\n\tdescription: string\n\t/** Zod schema for validating tool input */\n\tinputSchema: TInput\n\t/** Optional Zod schema for validating tool output */\n\toutputSchema?: TOutput\n\t/** Function that executes the tool's logic */\n\texecute: (args: {\n\t\tinput: z.infer<TInput>\n\t\truntime: AgentRuntime & TRuntimeExtension\n\t\tmessages: UIMessage[]\n\t}) => Promise<z.infer<TOutput>>\n}\n\n/**\n * Factory function to create tools with custom runtime extensions.\n * Provides proper type inference for input/output schemas and runtime extensions.\n */\nexport function toolFactory<TRuntimeExtension = DefaultRuntimeExtension>() {\n\treturn <\n\t\tTInput extends z.ZodTypeAny,\n\t\tTOutput extends z.ZodTypeAny = z.ZodTypeAny\n\t>(\n\t\tconfig: ToolConfig<TInput, TOutput, TRuntimeExtension>\n\t): Tool<TInput, TOutput, TRuntimeExtension> => {\n\t\treturn {\n\t\t\tdescription: config.description,\n\t\t\tinputSchema: config.inputSchema,\n\t\t\toutputSchema: config.outputSchema,\n\t\t\texecute: async (args) => {\n\t\t\t\tconst input = config.inputSchema.parse(args.input)\n\t\t\t\tconst result = await config.execute({\n\t\t\t\t\tinput,\n\t\t\t\t\truntime: args.runtime,\n\t\t\t\t\tmessages: args.messages\n\t\t\t\t})\n\t\t\t\tif (config.outputSchema) {\n\t\t\t\t\treturn config.outputSchema.parse(result)\n\t\t\t\t}\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Default tool factory with no runtime extensions.\n * Type-safe at creation time with proper schema inference.\n */\nexport const createTool = toolFactory()\n\n/**\n * Converts a custom Tool instance to AI SDK's tool format.\n * This adapter enables our tools to work with AI SDK's generateText/streamText functions.\n */\nexport function toAISDKTool<\n\tTRuntimeExtension = DefaultRuntimeExtension,\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny\n>(\n\ttool: Tool<TInput, TOutput, TRuntimeExtension>,\n\truntime: AgentRuntime & TRuntimeExtension,\n\tmessages: UIMessage[]\n): AISDKTool {\n\treturn {\n\t\tdescription: tool.description,\n\t\tinputSchema: tool.inputSchema,\n\t\texecute: async (args: z.infer<TInput>) => {\n\t\t\treturn tool.execute({\n\t\t\t\tinput: args,\n\t\t\t\truntime,\n\t\t\t\tmessages\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Converts a collection of custom tools to AI SDK format.\n * Useful for batch conversion when setting up multiple tools for AI SDK usage.\n */\nexport function toAISDKTools<\n\tTRuntimeExtension = DefaultRuntimeExtension,\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny\n>(\n\ttools: Record<string, Tool<TInput, TOutput, TRuntimeExtension>>,\n\truntime: AgentRuntime & TRuntimeExtension,\n\tmessages: UIMessage[]\n): Record<string, AISDKTool> {\n\tconst convertedTools: Record<string, AISDKTool> = {}\n\n\tfor (const [name, tool] of Object.entries(tools)) {\n\t\tconvertedTools[name] = toAISDKTool(tool, runtime, messages)\n\t}\n\n\treturn convertedTools\n}\n","/**\n * @fileoverview XMTP Communication Tools for Crypto Agents\n *\n * This module provides comprehensive XMTP messaging tools for crypto-enabled agents.\n * Includes capabilities for sending messages, replies, reactions, and managing conversations.\n *\n * @module XMTPTools\n */\n\nimport { z } from \"zod\"\nimport { createTool } from \"../core/tool\"\n\n/**\n * Send Reaction Tool\n *\n * Sends an emoji reaction to a specific message to indicate the message has been seen.\n * This is used to acknowledge receipt of messages before responding.\n *\n * @tool sendReaction\n * @category Communication\n *\n * @param {string} emoji - The emoji to send as a reaction (defaults to 👀)\n * @param {string} [referenceMessageId] - The message ID to react to (uses current message if not provided)\n *\n * @returns {Promise<{success: boolean, emoji: string, error?: string}>}\n */\nexport const sendReactionTool = createTool({\n\tid: \"sendReaction\",\n\tdescription:\n\t\t\"Send an emoji reaction to a message to indicate it has been seen\",\n\tinputSchema: z.object({\n\t\temoji: z\n\t\t\t.string()\n\t\t\t.default(\"👀\")\n\t\t\t.describe(\n\t\t\t\t\"The emoji to send as a reaction (supports common emoji like 👍, â¤ī¸, đŸ”Ĩ, etc.)\"\n\t\t\t),\n\t\treferenceMessageId: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"The message ID to react to (uses current message if not provided)\"\n\t\t\t)\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\temoji: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst currentMessage = runtime.message\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\tconst errorMsg = \"❌ XMTP service not available\"\n\t\t\t\treturn { success: false, emoji: input.emoji, error: errorMsg }\n\t\t\t}\n\n\t\t\tif (!currentMessage) {\n\t\t\t\tconst errorMsg = \"❌ No message to react to\"\n\t\t\t\treturn { success: false, emoji: input.emoji, error: errorMsg }\n\t\t\t}\n\n\t\t\t// Use provided reference message ID or current message ID\n\t\t\tconst messageIdToReactTo = input.referenceMessageId || currentMessage.id\n\n\t\t\tconsole.log(\n\t\t\t\t`👀 [sendReaction] Sending ${input.emoji} reaction to message ${messageIdToReactTo}`\n\t\t\t)\n\n\t\t\tconst reactionResult = await xmtpClient.sendReaction({\n\t\t\t\tmessageId: messageIdToReactTo,\n\t\t\t\temoji: input.emoji,\n\t\t\t\taction: \"added\"\n\t\t\t})\n\n\t\t\tif (!reactionResult.success) {\n\t\t\t\tconst errorMsg = `❌ Failed to send reaction: ${reactionResult.error || \"Unknown error\"}`\n\t\t\t\treturn { success: false, emoji: input.emoji, error: errorMsg }\n\t\t\t}\n\n\t\t\tconsole.log(`✅ [sendReaction] Successfully sent ${input.emoji} reaction`)\n\t\t\treturn { success: true, emoji: input.emoji }\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendReaction] Error:\", errorMessage)\n\t\t\treturn { success: false, emoji: input.emoji, error: errorMessage }\n\t\t}\n\t}\n})\n\n/**\n * Send Message Tool\n *\n * Sends a message to an XMTP conversation or creates a new conversation.\n *\n * @tool sendMessage\n * @category Communication\n *\n * @param {string} content - The message content to send\n * @param {string} [recipientAddress] - Recipient address for new conversations\n * @param {string} [conversationId] - Existing conversation ID to send to\n *\n * @returns {Promise<{success: boolean, messageId?: string, conversationId?: string, error?: string}>}\n */\nexport const sendMessageTool = createTool({\n\tid: \"sendMessage\",\n\tdescription: \"Send a message to an XMTP conversation\",\n\tinputSchema: z\n\t\t.object({\n\t\t\tcontent: z.string().describe(\"The message content to send\"),\n\t\t\trecipientAddress: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Recipient address for new conversations\"),\n\t\t\tconversationId: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Existing conversation ID to send to\")\n\t\t})\n\t\t.refine((data) => data.recipientAddress || data.conversationId, {\n\t\t\tmessage: \"Either recipientAddress or conversationId must be provided\"\n\t\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessageId: z.string().optional(),\n\t\tconversationId: z.string().optional(),\n\t\tcontent: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst { content, recipientAddress, conversationId } = input\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: \"XMTP service not available\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`đŸ’Ŧ [sendMessage] Sending message: \"${content.substring(0, 50)}${content.length > 50 ? \"...\" : \"\"}\"`\n\t\t\t)\n\n\t\t\tlet targetConversationId = conversationId\n\n\t\t\t// If no conversation ID provided, create or find conversation with recipient\n\t\t\tif (!targetConversationId && recipientAddress) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔍 [sendMessage] Creating/finding conversation with ${recipientAddress}`\n\t\t\t\t)\n\t\t\t\t// This would depend on your XMTP client implementation\n\t\t\t\t// For now, we'll assume the client handles conversation creation\n\t\t\t\ttargetConversationId = recipientAddress // Simplified for this example\n\t\t\t}\n\n\t\t\t// Send the message using the XMTP client\n\t\t\tconst messageResult = await xmtpClient.sendMessage({\n\t\t\t\tcontent\n\t\t\t})\n\n\t\t\tif (!messageResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: messageResult.error || \"Failed to send message\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(`✅ [sendMessage] Message sent successfully`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessageId: messageResult.data?.conversationId,\n\t\t\t\tconversationId: messageResult.data?.conversationId,\n\t\t\t\tcontent\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendMessage] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tcontent: input.content,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Send Reply Tool\n *\n * Sends a reply to a specific message in an XMTP conversation.\n *\n * @tool sendReply\n * @category Communication\n *\n * @param {string} content - The reply content to send\n * @param {string} [replyToMessageId] - Message ID to reply to (uses current message if not provided)\n *\n * @returns {Promise<{success: boolean, messageId?: string, replyToMessageId?: string, error?: string}>}\n */\nexport const sendReplyTool = createTool({\n\tid: \"sendReply\",\n\tdescription: \"Send a reply to a specific message in an XMTP conversation\",\n\tinputSchema: z.object({\n\t\tcontent: z.string().describe(\"The reply content to send\"),\n\t\treplyToMessageId: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Message ID to reply to (uses current message if not provided)\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessageId: z.string().optional(),\n\t\treplyToMessageId: z.string().optional(),\n\t\tcontent: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst currentMessage = runtime.message\n\t\t\tconst { content, replyToMessageId } = input\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: \"XMTP service not available\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!currentMessage && !replyToMessageId) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: \"No message to reply to\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst targetMessageId = replyToMessageId || currentMessage?.id\n\n\t\t\tconsole.log(\n\t\t\t\t`â†Šī¸ [sendReply] Sending reply to message ${targetMessageId}: \"${content.substring(0, 50)}${content.length > 50 ? \"...\" : \"\"}\"`\n\t\t\t)\n\n\t\t\tconst replyResult = await xmtpClient.sendReply({\n\t\t\t\tcontent,\n\t\t\t\tmessageId: targetMessageId\n\t\t\t})\n\n\t\t\tif (!replyResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\treplyToMessageId: targetMessageId,\n\t\t\t\t\terror: replyResult.error || \"Failed to send reply\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(`✅ [sendReply] Reply sent successfully`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessageId: replyResult.data?.conversationId,\n\t\t\t\treplyToMessageId: targetMessageId,\n\t\t\t\tcontent\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendReply] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tcontent: input.content,\n\t\t\t\treplyToMessageId: input.replyToMessageId,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Message Tool\n *\n * Retrieves a specific message by ID from the XMTP service.\n *\n * @tool getMessage\n * @category Communication\n *\n * @param {string} messageId - The message ID to retrieve\n *\n * @returns {Promise<{success: boolean, message?: object, error?: string}>}\n */\nexport const getMessageTool = createTool({\n\tid: \"getMessage\",\n\tdescription: \"Get a specific message by ID from XMTP\",\n\tinputSchema: z.object({\n\t\tmessageId: z.string().describe(\"The message ID to retrieve\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessage: z\n\t\t\t.object({\n\t\t\t\tid: z.string(),\n\t\t\t\tconversationId: z.string(),\n\t\t\t\tcontent: z.union([z.string(), z.record(z.unknown())]),\n\t\t\t\tsenderInboxId: z.string(),\n\t\t\t\tsentAt: z.string(),\n\t\t\t\tcontentType: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\ttypeId: z.string(),\n\t\t\t\t\t\tauthorityId: z.string().optional(),\n\t\t\t\t\t\tversionMajor: z.number().optional(),\n\t\t\t\t\t\tversionMinor: z.number().optional()\n\t\t\t\t\t})\n\t\t\t\t\t.optional()\n\t\t\t})\n\t\t\t.optional(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst { messageId } = input\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: \"XMTP service not available\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(`📜 [getMessage] Retrieving message ${messageId}`)\n\n\t\t\tconst messageResult = await xmtpClient.getMessage({\n\t\t\t\tmessageId\n\t\t\t})\n\n\t\t\tif (!messageResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: messageResult.error || \"Failed to get message\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getMessage] Retrieved message from ${messageResult.data?.senderInboxId}`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: messageResult.data\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getMessage] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Collection of XMTP communication tools for crypto agents\n *\n * These tools provide comprehensive messaging capabilities including sending messages,\n * replies, reactions, and retrieving message information.\n *\n * @namespace xmtpTools\n *\n * @property {Tool} sendMessage - Send a message to an XMTP conversation\n * @property {Tool} sendReply - Send a reply to a specific message\n * @property {Tool} sendReaction - Send an emoji reaction to a message\n * @property {Tool} getMessage - Get a specific message by ID\n */\nexport const xmtpTools = {\n\tsendMessage: sendMessageTool,\n\tsendReply: sendReplyTool,\n\tsendReaction: sendReactionTool,\n\tgetMessage: getMessageTool\n}\n"],"mappings":"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","names":["import_zod"]}
1
+ {"version":3,"sources":["../../src/tools/index.ts","../../src/tools/blockchain.ts","../../src/core/tool.ts","../../src/tools/xmtp.ts"],"sourcesContent":["/**\n * @fileoverview Hybrid Agent Tools Standard Library\n *\n * This module provides a comprehensive set of tools for building crypto-enabled agents.\n * Tools are organized by category and can be imported individually or as complete sets.\n *\n * @example\n * ```typescript\n * import { blockchainTools, xmtpTools } from \"hybrid/tools\"\n * import { Agent } from \"hybrid\"\n *\n * const agent = new Agent({\n * name: \"my-agent\",\n * model: myModel,\n * tools: {\n * ...blockchainTools,\n * ...xmtpTools\n * },\n * instructions: \"You are a crypto agent with blockchain and messaging capabilities.\",\n * createRuntime: (runtime) => ({\n * rpcUrl: process.env.RPC_URL,\n * privateKey: process.env.PRIVATE_KEY,\n * defaultChain: \"mainnet\" as const\n * })\n * })\n * ```\n *\n * @module HybridTools\n */\n\n// Export blockchain tools\nexport {\n\tblockchainTools,\n\testimateGasTool,\n\tgetBalanceTool,\n\tgetBlockTool,\n\tgetGasPriceTool,\n\tgetTransactionTool,\n\tsendTransactionTool,\n\ttype BlockchainRuntimeExtension\n} from \"./blockchain\"\n\n// Export XMTP tools\nexport {\n\tgetMessageTool,\n\tsendMessageTool,\n\tsendReactionTool,\n\tsendReplyTool,\n\txmtpTools\n} from \"./xmtp\"\n","/**\n * @fileoverview Blockchain Tools for Crypto Agents\n *\n * This module provides comprehensive blockchain interaction tools for crypto-enabled agents.\n * Supports Ethereum and other EVM-compatible chains with features like balance checking,\n * transaction sending, contract interaction, and more.\n *\n * @module BlockchainTools\n */\n\nimport {\n\tcreatePublicClient,\n\tcreateWalletClient,\n\tformatEther,\n\thttp,\n\tparseEther,\n\ttype Address,\n\ttype Hash\n} from \"viem\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport {\n\tarbitrum,\n\tbase,\n\tmainnet,\n\toptimism,\n\tpolygon,\n\tsepolia\n} from \"viem/chains\"\nimport { z } from \"zod\"\nimport { createTool } from \"../core/tool\"\n\n// Supported chains configuration\nconst SUPPORTED_CHAINS = {\n\tmainnet,\n\tsepolia,\n\tpolygon,\n\tarbitrum,\n\toptimism,\n\tbase\n} as const\n\ntype SupportedChain = keyof typeof SUPPORTED_CHAINS\n\n// Runtime extension interface for blockchain tools\nexport interface BlockchainRuntimeExtension {\n\trpcUrl?: string\n\tprivateKey?: string\n\tdefaultChain?: SupportedChain\n}\n\n/**\n * Get Balance Tool\n *\n * Retrieves the native token balance for a given address on a specified chain.\n *\n * @tool getBalance\n * @category Blockchain\n *\n * @param {string} address - The wallet address to check balance for\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, balance: string, balanceWei: string, address: string, chain: string, error?: string}>}\n */\nexport const getBalanceTool = createTool({\n\tid: \"getBalance\",\n\tdescription:\n\t\t\"Get the native token balance for a wallet address on a blockchain\",\n\tinputSchema: z.object({\n\t\taddress: z.string().describe(\"The wallet address to check balance for\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tbalance: z\n\t\t\t.string()\n\t\t\t.describe(\"Balance in human readable format (ETH, MATIC, etc.)\"),\n\t\tbalanceWei: z.string().describe(\"Balance in wei (smallest unit)\"),\n\t\taddress: z.string(),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { address, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\t// Use runtime RPC URL if provided, otherwise use default\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(`🔍 [getBalance] Checking balance for ${address} on ${chain}`)\n\n\t\t\tconst balanceWei = await client.getBalance({\n\t\t\t\taddress: address as Address\n\t\t\t})\n\n\t\t\tconst balance = formatEther(balanceWei)\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getBalance] Balance: ${balance} ${chainConfig.nativeCurrency.symbol}`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tbalance: `${balance} ${chainConfig.nativeCurrency.symbol}`,\n\t\t\t\tbalanceWei: balanceWei.toString(),\n\t\t\t\taddress,\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getBalance] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tbalance: \"0\",\n\t\t\t\tbalanceWei: \"0\",\n\t\t\t\taddress: input.address,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Transaction Tool\n *\n * Retrieves transaction details by transaction hash.\n *\n * @tool getTransaction\n * @category Blockchain\n *\n * @param {string} hash - The transaction hash to look up\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, transaction?: object, error?: string}>}\n */\nexport const getTransactionTool = createTool({\n\tid: \"getTransaction\",\n\tdescription: \"Get transaction details by transaction hash\",\n\tinputSchema: z.object({\n\t\thash: z.string().describe(\"The transaction hash to look up\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\ttransaction: z\n\t\t\t.object({\n\t\t\t\thash: z.string(),\n\t\t\t\tfrom: z.string(),\n\t\t\t\tto: z.string().nullable(),\n\t\t\t\tvalue: z.string(),\n\t\t\t\tgasUsed: z.string().optional(),\n\t\t\t\tgasPrice: z.string().optional(),\n\t\t\t\tblockNumber: z.string().optional(),\n\t\t\t\tstatus: z.string().optional()\n\t\t\t})\n\t\t\t.optional(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { hash, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`🔍 [getTransaction] Looking up transaction ${hash} on ${chain}`\n\t\t\t)\n\n\t\t\tconst transaction = await client.getTransaction({\n\t\t\t\thash: hash as Hash\n\t\t\t})\n\n\t\t\tconst receipt = await client\n\t\t\t\t.getTransactionReceipt({\n\t\t\t\t\thash: hash as Hash\n\t\t\t\t})\n\t\t\t\t.catch(() => null) // Transaction might be pending\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getTransaction] Found transaction from ${transaction.from} to ${transaction.to}`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\ttransaction: {\n\t\t\t\t\thash: transaction.hash,\n\t\t\t\t\tfrom: transaction.from,\n\t\t\t\t\tto: transaction.to,\n\t\t\t\t\tvalue: formatEther(transaction.value),\n\t\t\t\t\tgasUsed: receipt?.gasUsed.toString(),\n\t\t\t\t\tgasPrice: transaction.gasPrice?.toString(),\n\t\t\t\t\tblockNumber: transaction.blockNumber?.toString(),\n\t\t\t\t\tstatus:\n\t\t\t\t\t\treceipt?.status === \"success\"\n\t\t\t\t\t\t\t? \"success\"\n\t\t\t\t\t\t\t: receipt?.status === \"reverted\"\n\t\t\t\t\t\t\t\t? \"failed\"\n\t\t\t\t\t\t\t\t: \"pending\"\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getTransaction] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Send Transaction Tool\n *\n * Sends a native token transaction to another address.\n * Requires a private key to be configured in the runtime.\n *\n * @tool sendTransaction\n * @category Blockchain\n *\n * @param {string} to - The recipient address\n * @param {string} amount - The amount to send (in ETH, MATIC, etc.)\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, hash?: string, error?: string}>}\n */\nexport const sendTransactionTool = createTool({\n\tid: \"sendTransaction\",\n\tdescription: \"Send native tokens to another address\",\n\tinputSchema: z.object({\n\t\tto: z.string().describe(\"The recipient address\"),\n\t\tamount: z.string().describe(\"The amount to send (in ETH, MATIC, etc.)\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to send on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\thash: z.string().optional(),\n\t\tfrom: z.string().optional(),\n\t\tto: z.string(),\n\t\tamount: z.string(),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { to, amount, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst privateKey = (runtime as any).privateKey\n\t\t\tif (!privateKey) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tto,\n\t\t\t\t\tamount,\n\t\t\t\t\tchain,\n\t\t\t\t\terror: \"Private key not configured in runtime\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\t\t\tconst account = privateKeyToAccount(privateKey as `0x${string}`)\n\n\t\t\tconst client = createWalletClient({\n\t\t\t\taccount,\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`💸 [sendTransaction] Sending ${amount} ${chainConfig.nativeCurrency.symbol} to ${to} on ${chain}`\n\t\t\t)\n\n\t\t\tconst hash = await client.sendTransaction({\n\t\t\t\tto: to as Address,\n\t\t\t\tvalue: parseEther(amount)\n\t\t\t})\n\n\t\t\tconsole.log(`✅ [sendTransaction] Transaction sent: ${hash}`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\thash,\n\t\t\t\tfrom: account.address,\n\t\t\t\tto,\n\t\t\t\tamount,\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendTransaction] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tto: input.to,\n\t\t\t\tamount: input.amount,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Block Tool\n *\n * Retrieves information about a specific block.\n *\n * @tool getBlock\n * @category Blockchain\n *\n * @param {string} [blockNumber] - Block number (defaults to latest)\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, block?: object, error?: string}>}\n */\nexport const getBlockTool = createTool({\n\tid: \"getBlock\",\n\tdescription: \"Get information about a blockchain block\",\n\tinputSchema: z.object({\n\t\tblockNumber: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Block number (defaults to latest)\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tblock: z\n\t\t\t.object({\n\t\t\t\tnumber: z.string(),\n\t\t\t\thash: z.string(),\n\t\t\t\ttimestamp: z.string(),\n\t\t\t\ttransactionCount: z.number(),\n\t\t\t\tgasUsed: z.string(),\n\t\t\t\tgasLimit: z.string()\n\t\t\t})\n\t\t\t.optional(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { blockNumber, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`🔍 [getBlock] Getting block ${blockNumber || \"latest\"} on ${chain}`\n\t\t\t)\n\n\t\t\tconst block = await client.getBlock({\n\t\t\t\tblockNumber: blockNumber ? BigInt(blockNumber) : undefined\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getBlock] Found block ${block.number} with ${block.transactions.length} transactions`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tblock: {\n\t\t\t\t\tnumber: block.number.toString(),\n\t\t\t\t\thash: block.hash,\n\t\t\t\t\ttimestamp: block.timestamp.toString(),\n\t\t\t\t\ttransactionCount: block.transactions.length,\n\t\t\t\t\tgasUsed: block.gasUsed.toString(),\n\t\t\t\t\tgasLimit: block.gasLimit.toString()\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getBlock] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Gas Price Tool\n *\n * Retrieves current gas price information for a blockchain.\n *\n * @tool getGasPrice\n * @category Blockchain\n *\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, gasPrice?: string, error?: string}>}\n */\nexport const getGasPriceTool = createTool({\n\tid: \"getGasPrice\",\n\tdescription: \"Get current gas price for a blockchain\",\n\tinputSchema: z.object({\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to check on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tgasPrice: z.string().optional().describe(\"Gas price in gwei\"),\n\t\tgasPriceWei: z.string().optional().describe(\"Gas price in wei\"),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(`â›Ŋ [getGasPrice] Getting gas price for ${chain}`)\n\n\t\t\tconst gasPrice = await client.getGasPrice()\n\t\t\tconst gasPriceGwei = formatEther(gasPrice * BigInt(1000000000)) // Convert to gwei\n\n\t\t\tconsole.log(`✅ [getGasPrice] Current gas price: ${gasPriceGwei} gwei`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tgasPrice: `${gasPriceGwei} gwei`,\n\t\t\t\tgasPriceWei: gasPrice.toString(),\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getGasPrice] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Estimate Gas Tool\n *\n * Estimates gas required for a transaction.\n *\n * @tool estimateGas\n * @category Blockchain\n *\n * @param {string} to - The recipient address\n * @param {string} [amount] - The amount to send (defaults to 0)\n * @param {string} [data] - Transaction data (for contract calls)\n * @param {string} [chain] - The blockchain network (defaults to mainnet)\n *\n * @returns {Promise<{success: boolean, gasEstimate?: string, error?: string}>}\n */\nexport const estimateGasTool = createTool({\n\tid: \"estimateGas\",\n\tdescription: \"Estimate gas required for a transaction\",\n\tinputSchema: z.object({\n\t\tto: z.string().describe(\"The recipient address\"),\n\t\tamount: z\n\t\t\t.string()\n\t\t\t.default(\"0\")\n\t\t\t.describe(\"The amount to send (defaults to 0)\"),\n\t\tdata: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Transaction data (for contract calls)\"),\n\t\tchain: z\n\t\t\t.enum([\"mainnet\", \"sepolia\", \"polygon\", \"arbitrum\", \"optimism\", \"base\"])\n\t\t\t.default(\"mainnet\")\n\t\t\t.describe(\"The blockchain network to estimate on\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tgasEstimate: z.string().optional(),\n\t\tto: z.string(),\n\t\tamount: z.string(),\n\t\tchain: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst { to, amount, data, chain } = input\n\t\t\tconst chainConfig = SUPPORTED_CHAINS[chain]\n\n\t\t\tconst privateKey = (runtime as any).privateKey\n\t\t\tif (!privateKey) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tto,\n\t\t\t\t\tamount,\n\t\t\t\t\tchain,\n\t\t\t\t\terror: \"Private key not configured in runtime\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst rpcUrl =\n\t\t\t\t(runtime as any).rpcUrl || chainConfig.rpcUrls.default.http[0]\n\t\t\tconst account = privateKeyToAccount(privateKey as `0x${string}`)\n\n\t\t\tconst client = createPublicClient({\n\t\t\t\tchain: chainConfig,\n\t\t\t\ttransport: http(rpcUrl)\n\t\t\t})\n\n\t\t\tconsole.log(\n\t\t\t\t`â›Ŋ [estimateGas] Estimating gas for transaction to ${to} on ${chain}`\n\t\t\t)\n\n\t\t\tconst gasEstimate = await client.estimateGas({\n\t\t\t\taccount: account.address,\n\t\t\t\tto: to as Address,\n\t\t\t\tvalue: parseEther(amount),\n\t\t\t\tdata: data as `0x${string}` | undefined\n\t\t\t})\n\n\t\t\tconsole.log(`✅ [estimateGas] Estimated gas: ${gasEstimate.toString()}`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tgasEstimate: gasEstimate.toString(),\n\t\t\t\tto,\n\t\t\t\tamount,\n\t\t\t\tchain\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [estimateGas] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tto: input.to,\n\t\t\t\tamount: input.amount,\n\t\t\t\tchain: input.chain,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Collection of blockchain tools for crypto agents\n *\n * These tools provide comprehensive blockchain interaction capabilities including\n * balance checking, transaction sending, gas estimation, and more.\n *\n * @namespace blockchainTools\n *\n * @property {Tool} getBalance - Get native token balance for an address\n * @property {Tool} getTransaction - Get transaction details by hash\n * @property {Tool} sendTransaction - Send native tokens to another address\n * @property {Tool} getBlock - Get information about a blockchain block\n * @property {Tool} getGasPrice - Get current gas price for a blockchain\n * @property {Tool} estimateGas - Estimate gas required for a transaction\n */\nexport const blockchainTools = {\n\tgetBalance: getBalanceTool,\n\tgetTransaction: getTransactionTool,\n\tsendTransaction: sendTransactionTool,\n\tgetBlock: getBlockTool,\n\tgetGasPrice: getGasPriceTool,\n\testimateGas: estimateGasTool\n}\n","import { Tool as AISDKTool, type UIMessage } from \"ai\"\nimport { z } from \"zod\"\nimport { AgentRuntime } from \"../types\"\n\ntype DefaultRuntimeExtension = Record<string, never>\n\n/**\n * Configuration interface for creating custom tools that integrate with AI SDK.\n */\nexport interface ToolConfig<\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTRuntimeExtension = DefaultRuntimeExtension\n> {\n\t/** Unique identifier for the tool */\n\tid: string\n\t/** Human-readable description of what the tool does */\n\tdescription: string\n\t/** Zod schema for validating tool input */\n\tinputSchema: TInput\n\t/** Optional Zod schema for validating tool output */\n\toutputSchema?: TOutput\n\t/** Function that executes the tool's logic */\n\texecute: (args: {\n\t\tinput: z.infer<TInput>\n\t\truntime: AgentRuntime & TRuntimeExtension\n\t\tmessages: UIMessage[]\n\t}) => Promise<z.infer<TOutput>>\n}\n\n/**\n * Internal tool interface used throughout the agent framework.\n * Similar to ToolConfig but without the ID field, used after tool creation.\n */\nexport interface Tool<\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTRuntimeExtension = DefaultRuntimeExtension\n> {\n\t/** Human-readable description of what the tool does */\n\tdescription: string\n\t/** Zod schema for validating tool input */\n\tinputSchema: TInput\n\t/** Optional Zod schema for validating tool output */\n\toutputSchema?: TOutput\n\t/** Function that executes the tool's logic */\n\texecute: (args: {\n\t\tinput: z.infer<TInput>\n\t\truntime: AgentRuntime & TRuntimeExtension\n\t\tmessages: UIMessage[]\n\t}) => Promise<z.infer<TOutput>>\n}\n\n/**\n * Factory function to create tools with custom runtime extensions.\n * Provides proper type inference for input/output schemas and runtime extensions.\n */\nexport function toolFactory<TRuntimeExtension = DefaultRuntimeExtension>() {\n\treturn <\n\t\tTInput extends z.ZodTypeAny,\n\t\tTOutput extends z.ZodTypeAny = z.ZodTypeAny\n\t>(\n\t\tconfig: ToolConfig<TInput, TOutput, TRuntimeExtension>\n\t): Tool<TInput, TOutput, TRuntimeExtension> => {\n\t\treturn {\n\t\t\tdescription: config.description,\n\t\t\tinputSchema: config.inputSchema,\n\t\t\toutputSchema: config.outputSchema,\n\t\t\texecute: async (args) => {\n\t\t\t\tconst input = config.inputSchema.parse(args.input)\n\t\t\t\tconst result = await config.execute({\n\t\t\t\t\tinput,\n\t\t\t\t\truntime: args.runtime,\n\t\t\t\t\tmessages: args.messages\n\t\t\t\t})\n\t\t\t\tif (config.outputSchema) {\n\t\t\t\t\treturn config.outputSchema.parse(result)\n\t\t\t\t}\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Default tool factory with no runtime extensions.\n * Type-safe at creation time with proper schema inference.\n */\nexport const createTool = toolFactory()\n\n/**\n * Converts a custom Tool instance to AI SDK's tool format.\n * This adapter enables our tools to work with AI SDK's generateText/streamText functions.\n */\nexport function toAISDKTool<\n\tTRuntimeExtension = DefaultRuntimeExtension,\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny\n>(\n\ttool: Tool<TInput, TOutput, TRuntimeExtension>,\n\truntime: AgentRuntime & TRuntimeExtension,\n\tmessages: UIMessage[]\n): AISDKTool {\n\treturn {\n\t\tdescription: tool.description,\n\t\tinputSchema: tool.inputSchema,\n\t\texecute: async (args: z.infer<TInput>) => {\n\t\t\treturn tool.execute({\n\t\t\t\tinput: args,\n\t\t\t\truntime,\n\t\t\t\tmessages\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Converts a collection of custom tools to AI SDK format.\n * Useful for batch conversion when setting up multiple tools for AI SDK usage.\n */\nexport function toAISDKTools<\n\tTRuntimeExtension = DefaultRuntimeExtension,\n\tTInput extends z.ZodTypeAny = z.ZodTypeAny,\n\tTOutput extends z.ZodTypeAny = z.ZodTypeAny\n>(\n\ttools: Record<string, Tool<TInput, TOutput, TRuntimeExtension>>,\n\truntime: AgentRuntime & TRuntimeExtension,\n\tmessages: UIMessage[]\n): Record<string, AISDKTool> {\n\tconst convertedTools: Record<string, AISDKTool> = {}\n\n\tfor (const [name, tool] of Object.entries(tools)) {\n\t\tconvertedTools[name] = toAISDKTool(tool, runtime, messages)\n\t}\n\n\treturn convertedTools\n}\n","/**\n * @fileoverview XMTP Communication Tools for Crypto Agents\n *\n * This module provides comprehensive XMTP messaging tools for crypto-enabled agents.\n * Includes capabilities for sending messages, replies, reactions, and managing conversations.\n *\n * @module XMTPTools\n */\n\nimport { z } from \"zod\"\nimport { createTool } from \"../core/tool\"\n\n/**\n * Send Reaction Tool\n *\n * Sends an emoji reaction to a specific message to indicate the message has been seen.\n * This is used to acknowledge receipt of messages before responding.\n *\n * @tool sendReaction\n * @category Communication\n *\n * @param {string} emoji - The emoji to send as a reaction (defaults to 👀)\n * @param {string} [referenceMessageId] - The message ID to react to (uses current message if not provided)\n *\n * @returns {Promise<{success: boolean, emoji: string, error?: string}>}\n */\nexport const sendReactionTool = createTool({\n\tid: \"sendReaction\",\n\tdescription:\n\t\t\"Send an emoji reaction to a message to indicate it has been seen\",\n\tinputSchema: z.object({\n\t\temoji: z\n\t\t\t.string()\n\t\t\t.default(\"👀\")\n\t\t\t.describe(\n\t\t\t\t\"The emoji to send as a reaction (supports common emoji like 👍, â¤ī¸, đŸ”Ĩ, etc.)\"\n\t\t\t),\n\t\treferenceMessageId: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"The message ID to react to (uses current message if not provided)\"\n\t\t\t)\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\temoji: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst currentMessage = runtime.message\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\tconst errorMsg = \"❌ XMTP service not available\"\n\t\t\t\treturn { success: false, emoji: input.emoji, error: errorMsg }\n\t\t\t}\n\n\t\t\tif (!currentMessage) {\n\t\t\t\tconst errorMsg = \"❌ No message to react to\"\n\t\t\t\treturn { success: false, emoji: input.emoji, error: errorMsg }\n\t\t\t}\n\n\t\t\t// Use provided reference message ID or current message ID\n\t\t\tconst messageIdToReactTo = input.referenceMessageId || currentMessage.id\n\n\t\t\tconsole.log(\n\t\t\t\t`👀 [sendReaction] Sending ${input.emoji} reaction to message ${messageIdToReactTo}`\n\t\t\t)\n\n\t\t\tconst reactionResult = await xmtpClient.sendReaction({\n\t\t\t\tmessageId: messageIdToReactTo,\n\t\t\t\temoji: input.emoji,\n\t\t\t\taction: \"added\"\n\t\t\t})\n\n\t\t\tif (!reactionResult.success) {\n\t\t\t\tconst errorMsg = `❌ Failed to send reaction: ${reactionResult.error || \"Unknown error\"}`\n\t\t\t\treturn { success: false, emoji: input.emoji, error: errorMsg }\n\t\t\t}\n\n\t\t\tconsole.log(`✅ [sendReaction] Successfully sent ${input.emoji} reaction`)\n\t\t\treturn { success: true, emoji: input.emoji }\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendReaction] Error:\", errorMessage)\n\t\t\treturn { success: false, emoji: input.emoji, error: errorMessage }\n\t\t}\n\t}\n})\n\n/**\n * Send Message Tool\n *\n * Sends a message to an XMTP conversation or creates a new conversation.\n *\n * @tool sendMessage\n * @category Communication\n *\n * @param {string} content - The message content to send\n * @param {string} [recipientAddress] - Recipient address for new conversations\n * @param {string} [conversationId] - Existing conversation ID to send to\n *\n * @returns {Promise<{success: boolean, messageId?: string, conversationId?: string, error?: string}>}\n */\nexport const sendMessageTool = createTool({\n\tid: \"sendMessage\",\n\tdescription: \"Send a message to an XMTP conversation\",\n\tinputSchema: z\n\t\t.object({\n\t\t\tcontent: z.string().describe(\"The message content to send\"),\n\t\t\trecipientAddress: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Recipient address for new conversations\"),\n\t\t\tconversationId: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Existing conversation ID to send to\")\n\t\t})\n\t\t.refine((data) => data.recipientAddress || data.conversationId, {\n\t\t\tmessage: \"Either recipientAddress or conversationId must be provided\"\n\t\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessageId: z.string().optional(),\n\t\tconversationId: z.string().optional(),\n\t\tcontent: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst { content, recipientAddress, conversationId } = input\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: \"XMTP service not available\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`đŸ’Ŧ [sendMessage] Sending message: \"${content.substring(0, 50)}${content.length > 50 ? \"...\" : \"\"}\"`\n\t\t\t)\n\n\t\t\tlet targetConversationId = conversationId\n\n\t\t\t// If no conversation ID provided, create or find conversation with recipient\n\t\t\tif (!targetConversationId && recipientAddress) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔍 [sendMessage] Creating/finding conversation with ${recipientAddress}`\n\t\t\t\t)\n\t\t\t\t// This would depend on your XMTP client implementation\n\t\t\t\t// For now, we'll assume the client handles conversation creation\n\t\t\t\ttargetConversationId = recipientAddress // Simplified for this example\n\t\t\t}\n\n\t\t\t// Send the message using the XMTP client\n\t\t\tconst messageResult = await xmtpClient.sendMessage({\n\t\t\t\tcontent\n\t\t\t})\n\n\t\t\tif (!messageResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: messageResult.error || \"Failed to send message\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(`✅ [sendMessage] Message sent successfully`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessageId: messageResult.data?.conversationId,\n\t\t\t\tconversationId: messageResult.data?.conversationId,\n\t\t\t\tcontent\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendMessage] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tcontent: input.content,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Send Reply Tool\n *\n * Sends a reply to a specific message in an XMTP conversation.\n *\n * @tool sendReply\n * @category Communication\n *\n * @param {string} content - The reply content to send\n * @param {string} [replyToMessageId] - Message ID to reply to (uses current message if not provided)\n *\n * @returns {Promise<{success: boolean, messageId?: string, replyToMessageId?: string, error?: string}>}\n */\nexport const sendReplyTool = createTool({\n\tid: \"sendReply\",\n\tdescription: \"Send a reply to a specific message in an XMTP conversation\",\n\tinputSchema: z.object({\n\t\tcontent: z.string().describe(\"The reply content to send\"),\n\t\treplyToMessageId: z\n\t\t\t.string()\n\t\t\t.optional()\n\t\t\t.describe(\"Message ID to reply to (uses current message if not provided)\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessageId: z.string().optional(),\n\t\treplyToMessageId: z.string().optional(),\n\t\tcontent: z.string(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst currentMessage = runtime.message\n\t\t\tconst { content, replyToMessageId } = input\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: \"XMTP service not available\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!currentMessage && !replyToMessageId) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\terror: \"No message to reply to\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst targetMessageId = replyToMessageId || currentMessage?.id\n\n\t\t\tconsole.log(\n\t\t\t\t`â†Šī¸ [sendReply] Sending reply to message ${targetMessageId}: \"${content.substring(0, 50)}${content.length > 50 ? \"...\" : \"\"}\"`\n\t\t\t)\n\n\t\t\tconst replyResult = await xmtpClient.sendReply({\n\t\t\t\tcontent,\n\t\t\t\tmessageId: targetMessageId\n\t\t\t})\n\n\t\t\tif (!replyResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tcontent,\n\t\t\t\t\treplyToMessageId: targetMessageId,\n\t\t\t\t\terror: replyResult.error || \"Failed to send reply\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(`✅ [sendReply] Reply sent successfully`)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessageId: replyResult.data?.conversationId,\n\t\t\t\treplyToMessageId: targetMessageId,\n\t\t\t\tcontent\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [sendReply] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tcontent: input.content,\n\t\t\t\treplyToMessageId: input.replyToMessageId,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Get Message Tool\n *\n * Retrieves a specific message by ID from the XMTP service.\n *\n * @tool getMessage\n * @category Communication\n *\n * @param {string} messageId - The message ID to retrieve\n *\n * @returns {Promise<{success: boolean, message?: object, error?: string}>}\n */\nexport const getMessageTool = createTool({\n\tid: \"getMessage\",\n\tdescription: \"Get a specific message by ID from XMTP\",\n\tinputSchema: z.object({\n\t\tmessageId: z.string().describe(\"The message ID to retrieve\")\n\t}),\n\toutputSchema: z.object({\n\t\tsuccess: z.boolean(),\n\t\tmessage: z\n\t\t\t.object({\n\t\t\t\tid: z.string(),\n\t\t\t\tconversationId: z.string(),\n\t\t\t\tcontent: z.union([z.string(), z.record(z.unknown())]),\n\t\t\t\tsenderInboxId: z.string(),\n\t\t\t\tsentAt: z.string(),\n\t\t\t\tcontentType: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\ttypeId: z.string(),\n\t\t\t\t\t\tauthorityId: z.string().optional(),\n\t\t\t\t\t\tversionMajor: z.number().optional(),\n\t\t\t\t\t\tversionMinor: z.number().optional()\n\t\t\t\t\t})\n\t\t\t\t\t.optional()\n\t\t\t})\n\t\t\t.optional(),\n\t\terror: z.string().optional()\n\t}),\n\texecute: async ({ input, runtime }) => {\n\t\ttry {\n\t\t\tconst xmtpClient = runtime.xmtpClient\n\t\t\tconst { messageId } = input\n\n\t\t\tif (!xmtpClient) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: \"XMTP service not available\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(`📜 [getMessage] Retrieving message ${messageId}`)\n\n\t\t\tconst messageResult = await xmtpClient.getMessage({\n\t\t\t\tmessageId\n\t\t\t})\n\n\t\t\tif (!messageResult.success) {\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: messageResult.error || \"Failed to get message\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`✅ [getMessage] Retrieved message from ${messageResult.data?.senderInboxId}`\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: messageResult.data\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\tconsole.error(\"❌ [getMessage] Error:\", errorMessage)\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage\n\t\t\t}\n\t\t}\n\t}\n})\n\n/**\n * Collection of XMTP communication tools for crypto agents\n *\n * These tools provide comprehensive messaging capabilities including sending messages,\n * replies, reactions, and retrieving message information.\n *\n * @namespace xmtpTools\n *\n * @property {Tool} sendMessage - Send a message to an XMTP conversation\n * @property {Tool} sendReply - Send a reply to a specific message\n * @property {Tool} sendReaction - Send an emoji reaction to a message\n * @property {Tool} getMessage - Get a specific message by ID\n */\nexport const xmtpTools = {\n\tsendMessage: sendMessageTool,\n\tsendReply: sendReplyTool,\n\tsendReaction: sendReactionTool,\n\tgetMessage: getMessageTool\n}\n"],"mappings":"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","names":["import_zod"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hybrid",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "keywords": [
5
5
  "xmtp",
6
6
  "agent",
@@ -44,8 +44,8 @@
44
44
  "viem": "^2.33.3",
45
45
  "wagmi": "^2.15.6",
46
46
  "zod": "^3.23.8",
47
- "@hybrd/utils": "1.2.4",
48
- "@hybrd/xmtp": "1.2.4"
47
+ "@hybrd/utils": "1.2.6",
48
+ "@hybrd/xmtp": "1.2.6"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/degit": "^2.8.4",
@@ -10,7 +10,7 @@
10
10
  * import { Agent } from "hybrid"
11
11
  *
12
12
  * const agent = new Agent({
13
- * name: "crypto-agent",
13
+ * name: "my-agent",
14
14
  * model: myModel,
15
15
  * tools: {
16
16
  * ...blockchainTools,