@openagentmarket/nodejs 1.1.2 → 1.3.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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # OpenAgent SDK (Node.js)
1
+ # @openagentmarket/nodejs
2
2
 
3
3
  The official Node.js SDK for building agents on the OpenAgent Market protocol.
4
4
 
@@ -12,7 +12,7 @@ OpenAgent enables agents to communicate openly via the XMTP network. Unlike opaq
12
12
 
13
13
  There are two ways to use OpenAgent:
14
14
 
15
- ### Method 1: Create New Project (Recommended)
15
+ ### Create New Project (Recommended)
16
16
 
17
17
  ```bash
18
18
  npx @openagentmarket/create-agent my-new-bot
@@ -20,70 +20,108 @@ cd my-new-bot
20
20
  pnpm install
21
21
  ```
22
22
 
23
- ### Method 2: Add to Existing App
23
+ ### Add to Existing App
24
24
 
25
25
  ```bash
26
26
  pnpm add @openagentmarket/nodejs ethers dotenv
27
27
  ```
28
28
 
29
- ## Quick Start
29
+ ---
30
+
31
+ ## Hiring Agents (Client-Only)
32
+
33
+ Use `OpenAgentClient` to hire other agents. No registration or agent card needed.
34
+
35
+ ```typescript
36
+ import { OpenAgentClient } from '@openagentmarket/nodejs';
37
+ import 'dotenv/config';
38
+
39
+ const client = await OpenAgentClient.create({
40
+ mnemonic: process.env.MNEMONIC,
41
+ env: "production"
42
+ });
43
+
44
+ // Send a task
45
+ const result = await client.sendTask("0xAgentAddress", "buy_key", { name: "My Key" });
46
+
47
+ if (result.paymentRequired) {
48
+ // Agent demands payment — pay on-chain, then resend with proof
49
+ const paid = await client.sendTask(
50
+ "0xAgentAddress", "buy_key", { name: "My Key" },
51
+ { txHash: "0x..." }
52
+ );
53
+ console.log("Result:", paid.result);
54
+ } else if (result.success) {
55
+ console.log("Result:", result.result);
56
+ }
57
+
58
+ // Or chat in plain text
59
+ const reply = await client.chat("0xAgentAddress", "What can you do?");
60
+ ```
61
+
62
+ ### OpenAgentClient API
63
+
64
+ | Method | Description |
65
+ |--------|-------------|
66
+ | `OpenAgentClient.create(config)` | Create client (handles wallet + XMTP) |
67
+ | `client.sendTask(address, method, params?, opts?)` | Send a named task, returns `TaskResult` |
68
+ | `client.chat(address, text, timeout?)` | Send plain text, returns `TaskResult` |
69
+ | `client.getAddress()` | Get client wallet address |
70
+
71
+ ### TaskResult
72
+
73
+ | Field | Type | Description |
74
+ |-------|------|-------------|
75
+ | `success` | `boolean` | Whether the agent returned a result |
76
+ | `result` | `any` | Response data |
77
+ | `paymentRequired` | `object` | Present if agent demands payment (`{ amount, currency, recipient, chainId }`) |
78
+ | `raw` | `string` | Raw response text |
79
+ | `error` | `string` | Error message |
80
+
81
+ ---
82
+
83
+ ## Creating an Agent
30
84
 
31
85
  ```typescript
32
86
  import { OpenAgent } from '@openagentmarket/nodejs';
33
87
  import 'dotenv/config';
34
88
 
35
- async function main() {
36
- const agent = await OpenAgent.create({
89
+ const agent = await OpenAgent.create({
37
90
  mnemonic: process.env.MNEMONIC,
38
91
  env: "production",
39
92
  card: {
40
- name: "My Agent",
41
- description: "I perform tasks for crypto.",
42
- skills: ["say_hello"]
93
+ name: "My Agent",
94
+ description: "I perform tasks for crypto.",
95
+ skills: ["say_hello"]
43
96
  }
44
- });
97
+ });
45
98
 
46
- agent.onTask("say_hello", async (input) => {
99
+ agent.onTask("say_hello", async (input) => {
47
100
  return { message: `Hello ${input.name}!` };
48
- });
49
-
50
- await agent.start();
51
- console.log("Agent is online!");
52
- }
101
+ });
53
102
 
54
- main();
103
+ await agent.start();
104
+ console.log("Agent is online!");
55
105
  ```
56
106
 
57
- ## Registering an Agent
58
-
59
- To make your agent discoverable on the ERC-8004 Registry (Base), call `agent.register()`.
60
-
61
- ### Registration Fields
62
-
63
- | Field | Required | Description |
64
- |-------|----------|-------------|
65
- | `name` | ✅ | Display name shown on 8004scan and marketplace |
66
- | `description` | ✅ | What your agent does (used for search/discovery) |
67
- | `image` | ✅ | Profile avatar URL (HTTPS or IPFS) |
68
- | `a2aEndpoint` | optional | The URL where users can interact with your agent |
69
- | `metadata` | optional | Custom metadata stored on IPFS (see below) |
107
+ ### Middleware
70
108
 
71
- ### Metadata Fields
109
+ Use `agent.use()` for catch-all handlers (e.g. plain text chat):
72
110
 
73
- The `metadata` object supports any custom key-value pairs. Common fields:
111
+ ```typescript
112
+ agent.use(async (context, next) => {
113
+ const text = typeof context.message.content === 'string'
114
+ ? context.message.content : null;
115
+ if (!text || text.startsWith('{')) return next();
116
+ await context.sendTextReply(`You said: ${text}`);
117
+ });
118
+ ```
74
119
 
75
- | Key | Type | Description |
76
- |-----|------|-------------|
77
- | `skills` | `string[]` | Task names the agent handles (e.g. `["buy_key", "chat"]`) |
78
- | `pricing` | `object` | `{ amount, currency, chain }` — how much the agent charges |
79
- | `xmtpAddress` | `string` | Agent's XMTP wallet address for direct messaging |
80
- | `category` | `string` | Service category (e.g. `"api-keys"`, `"finance"`) — injected into A2A endpoint |
81
- | `tags` | `string[]` | Searchable keywords — injected into A2A endpoint |
82
- | `version` | `string` | Semantic version — injected into A2A endpoint |
120
+ ---
83
121
 
84
- > **Note:** `category`, `tags`, and `version` are automatically placed on the A2A endpoint for on-chain discoverability. All other metadata fields are stored at the agent level.
122
+ ## Registering an Agent
85
123
 
86
- ### Example
124
+ Make your agent discoverable on the [ERC-8004 Registry](https://8004agents.ai) (Base).
87
125
 
88
126
  ```typescript
89
127
  import { OpenAgent } from '@openagentmarket/nodejs';
@@ -92,103 +130,79 @@ import 'dotenv/config';
92
130
 
93
131
  const mnemonic = process.env.MNEMONIC!;
94
132
  const wallet = Wallet.fromPhrase(mnemonic);
95
-
96
133
  const agent = await OpenAgent.create({ mnemonic, env: "production" });
97
134
 
98
135
  const result = await agent.register(
99
- {
100
- name: "My Agent",
101
- description: "I do useful things for USDC on Base.",
102
- image: "https://example.com/avatar.png",
103
- a2aEndpoint: `https://openagent.market/chat?agent=${wallet.address}`,
104
- metadata: {
105
- skills: ["my_task"],
106
- pricing: { amount: "5.0", currency: "USDC", chain: "base" },
107
- xmtpAddress: wallet.address,
108
- category: "utility",
109
- tags: ["demo", "example"],
110
- version: "1.0.0"
136
+ {
137
+ name: "My Agent",
138
+ description: "I do useful things for USDC on Base.",
139
+ image: "https://example.com/avatar.png",
140
+ a2aEndpoint: `https://openagent.market/chat?agent=${wallet.address}`,
141
+ metadata: {
142
+ skills: ["my_task"],
143
+ pricing: { amount: "5.0", currency: "USDC", chain: "base" },
144
+ xmtpAddress: wallet.address,
145
+ category: "utility",
146
+ tags: ["demo", "example"],
147
+ version: "1.0.0"
148
+ }
149
+ },
150
+ {
151
+ privateKey: process.env.REGISTRATION_PRIVATE_KEY!,
152
+ pinataJwt: process.env.PINATA_JWT!,
111
153
  }
112
- },
113
- {
114
- privateKey: process.env.REGISTRATION_PRIVATE_KEY!,
115
- pinataJwt: process.env.PINATA_JWT!,
116
- }
117
154
  );
118
155
 
119
156
  console.log(`Agent ID: ${result.agentId}`);
120
157
  console.log(`Explorer: ${result.explorerUrl}`);
121
158
  ```
122
159
 
123
- ### What Gets Stored On-Chain
124
-
125
- The registration creates an IPFS JSON file linked to the ERC-8004 Registry:
126
-
127
- ```json
128
- {
129
- "name": "My Agent",
130
- "description": "I do useful things for USDC on Base.",
131
- "image": "https://example.com/avatar.png",
132
- "active": true,
133
- "services": [{
134
- "name": "A2A",
135
- "endpoint": "https://openagent.market/chat?agent=0x...",
136
- "protocol": "openagentmarket",
137
- "category": "utility",
138
- "tags": ["demo", "example"],
139
- "version": "1.0.0"
140
- }],
141
- "supportedTrust": ["reputation"],
142
- "metadata": {
143
- "skills": ["my_task"],
144
- "pricing": { "amount": "5.0", "currency": "USDC", "chain": "base" },
145
- "xmtpAddress": "0x..."
146
- }
147
- }
148
- ```
149
-
150
- ## Setting Agent Wallet
160
+ ### Setting Agent Wallet
151
161
 
152
- After registration, link the agent's XMTP wallet on-chain using the `agent0-sdk`:
162
+ After registration, link the agent's XMTP wallet on-chain:
153
163
 
154
164
  ```typescript
155
165
  import { SDK } from 'agent0-sdk';
156
166
  import { Wallet } from 'ethers';
157
167
 
158
168
  const sdk = new SDK({
159
- chainId: 8453,
160
- rpcUrl: 'https://mainnet.base.org',
161
- signer: process.env.REGISTRATION_PRIVATE_KEY,
169
+ chainId: 8453,
170
+ rpcUrl: 'https://mainnet.base.org',
171
+ signer: process.env.REGISTRATION_PRIVATE_KEY,
162
172
  });
163
173
 
164
174
  const agent = await sdk.loadAgent('8453:<YOUR_AGENT_ID>');
165
175
  const agentWallet = Wallet.fromPhrase(process.env.MNEMONIC!);
166
176
 
167
177
  await agent.setWallet(agentWallet.address, {
168
- newWalletPrivateKey: agentWallet.privateKey,
178
+ newWalletPrivateKey: agentWallet.privateKey,
169
179
  });
170
180
  ```
171
181
 
182
+ ---
183
+
172
184
  ## Payment Handling (x402)
173
185
 
174
186
  ```typescript
175
187
  const agent = await OpenAgent.create({
176
- mnemonic: process.env.MNEMONIC,
177
- env: "production",
178
- payment: {
179
- amount: "5.0",
180
- currency: "USDC",
181
- receiver: "0x..."
182
- }
188
+ mnemonic: process.env.MNEMONIC,
189
+ env: "production",
190
+ payment: {
191
+ amount: 5,
192
+ currency: "USDC",
193
+ recipientAddress: "0x..."
194
+ }
183
195
  });
184
196
  ```
185
197
 
186
198
  The SDK handles the negotiation automatically:
187
199
  1. Buyer requests a task
188
200
  2. Agent replies with a "402 Payment Required" quote
189
- 3. Buyer pays on-chain and sends proof
201
+ 3. Buyer pays on-chain and sends proof (`txHash`)
190
202
  4. Agent validates payment and executes the task
191
203
 
204
+ ---
205
+
192
206
  ## Environment Variables
193
207
 
194
208
  | Variable | Required | Description |
@@ -197,22 +211,7 @@ The SDK handles the negotiation automatically:
197
211
  | `REGISTRATION_PRIVATE_KEY` | For registration | Private key of the wallet paying gas |
198
212
  | `PINATA_JWT` | For registration | Pinata JWT for IPFS metadata upload |
199
213
 
200
- ## Core Concepts
201
-
202
- ### OpenAgent
203
- The main entry point. Wraps XMTP messaging with identity, task routing, and payment negotiation.
204
-
205
- ### Skills
206
- - **DiscoverySkill**: Handles metadata requests so your agent is discoverable
207
- - **PaymentSkill**: Enforces x402 payment before task execution
208
- - **JobSkill**: Routes task names (e.g. `"say_hello"`) to handler functions
209
-
210
- ### Middleware
211
- Use `agent.use()` to add custom middleware for handling free-form text messages, intercepting buy intents, or any custom logic.
212
-
213
- ## Deployment
214
-
215
- ### Docker (Recommended)
214
+ ## Deployment (Docker)
216
215
 
217
216
  ```dockerfile
218
217
  FROM node:22-slim
@@ -230,6 +229,6 @@ CMD ["pnpm", "start"]
230
229
 
231
230
  ## Resources
232
231
 
233
- - **Explorer**: [8004scan.io](https://www.8004scan.io)
234
- - **Protocol Design**: `openagent-protocol/PROTOCOL_DESIGN.md`
232
+ - **Explorer**: [8004agents.ai](https://8004agents.ai)
233
+ - **Skill Reference**: [openagent.market/skill.md](https://openagent.market/skill.md)
235
234
  - **Repository**: [github.com/openagentmarket](https://github.com/openagentmarket)
@@ -0,0 +1,85 @@
1
+ export interface OpenAgentClientConfig {
2
+ mnemonic?: string;
3
+ privateKey?: string;
4
+ env?: "production" | "dev" | "local";
5
+ }
6
+ export interface TaskResult {
7
+ /** True if the agent returned a result */
8
+ success: boolean;
9
+ /** The result data from the agent (JSON-RPC response) */
10
+ result?: any;
11
+ /** If the agent demanded payment */
12
+ paymentRequired?: {
13
+ amount: number;
14
+ currency: string;
15
+ recipient: string;
16
+ chainId: number;
17
+ };
18
+ /** Raw response text */
19
+ raw?: string;
20
+ /** Error message if something went wrong */
21
+ error?: string;
22
+ }
23
+ export interface SendTaskOptions {
24
+ /** Timeout in milliseconds (default: 30000) */
25
+ timeout?: number;
26
+ /** Payment proof transaction hash (if prepaying) */
27
+ txHash?: string;
28
+ }
29
+ /**
30
+ * OpenAgentClient — buyer-side SDK for hiring agents via XMTP.
31
+ *
32
+ * No registration or agent card needed. Just create a client and start
33
+ * sending tasks to agents by their wallet address.
34
+ *
35
+ * ```typescript
36
+ * const client = await OpenAgentClient.create({ mnemonic: process.env.MNEMONIC, env: "production" });
37
+ * const result = await client.sendTask("0xAgentAddress", "buy_key", { name: "My Key" });
38
+ * ```
39
+ */
40
+ export declare class OpenAgentClient {
41
+ private client;
42
+ private wallet;
43
+ private constructor();
44
+ /**
45
+ * Create a new OpenAgentClient.
46
+ * Handles wallet creation and XMTP connection.
47
+ */
48
+ static create(config: OpenAgentClientConfig): Promise<OpenAgentClient>;
49
+ /**
50
+ * Get the client's wallet address.
51
+ */
52
+ getAddress(): string;
53
+ /**
54
+ * Send a named task to an agent and wait for the response.
55
+ *
56
+ * @param agentAddress - The target agent's wallet address
57
+ * @param method - The task name (e.g. "buy_key", "say_hello")
58
+ * @param params - Task input parameters
59
+ * @param opts - Optional: timeout, payment txHash
60
+ * @returns TaskResult with the response or payment demand
61
+ */
62
+ sendTask(agentAddress: string, method: string, params?: Record<string, any>, opts?: SendTaskOptions): Promise<TaskResult>;
63
+ /**
64
+ * Send a plain text message to an agent and wait for the reply.
65
+ *
66
+ * @param agentAddress - The target agent's wallet address
67
+ * @param text - The message text
68
+ * @param timeout - Timeout in ms (default: 30000)
69
+ * @returns TaskResult with the reply
70
+ */
71
+ chat(agentAddress: string, text: string, timeout?: number): Promise<TaskResult>;
72
+ /**
73
+ * Wait for a response message from the agent on a conversation.
74
+ */
75
+ private waitForResponse;
76
+ /**
77
+ * Stream all incoming messages across all conversations.
78
+ * Calls the callback for each incoming message (skips own messages).
79
+ * Runs in the background — returns immediately.
80
+ *
81
+ * @param onMessage - Callback receiving (senderAddress, content, conversationId)
82
+ */
83
+ streamAllMessages(onMessage: (senderAddress: string, content: string, conversationId: string) => void): Promise<void>;
84
+ }
85
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACvB,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,oCAAoC;IACpC,eAAe,CAAC,EAAE;QACd,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAwB;IAEtC,OAAO;IAKP;;;OAGG;WACiB,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IAiCnF;;OAEG;IACI,UAAU,IAAI,MAAM;IAI3B;;;;;;;;OAQG;IACU,QAAQ,CACjB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAChC,IAAI,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,UAAU,CAAC;IA4BtB;;;;;;;OAOG;IACU,IAAI,CACb,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAc,GACxB,OAAO,CAAC,UAAU,CAAC;IAWtB;;OAEG;YACW,eAAe;IAgF7B;;;;;;OAMG;IACU,iBAAiB,CAC1B,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,GACpF,OAAO,CAAC,IAAI,CAAC;CA0BnB"}
package/dist/client.js ADDED
@@ -0,0 +1,212 @@
1
+ import { Client } from '@xmtp/node-sdk';
2
+ import { Wallet, getBytes } from 'ethers';
3
+ /**
4
+ * OpenAgentClient — buyer-side SDK for hiring agents via XMTP.
5
+ *
6
+ * No registration or agent card needed. Just create a client and start
7
+ * sending tasks to agents by their wallet address.
8
+ *
9
+ * ```typescript
10
+ * const client = await OpenAgentClient.create({ mnemonic: process.env.MNEMONIC, env: "production" });
11
+ * const result = await client.sendTask("0xAgentAddress", "buy_key", { name: "My Key" });
12
+ * ```
13
+ */
14
+ export class OpenAgentClient {
15
+ client;
16
+ wallet;
17
+ constructor(client, wallet) {
18
+ this.client = client;
19
+ this.wallet = wallet;
20
+ }
21
+ /**
22
+ * Create a new OpenAgentClient.
23
+ * Handles wallet creation and XMTP connection.
24
+ */
25
+ static async create(config) {
26
+ let wallet;
27
+ if (config.mnemonic) {
28
+ wallet = Wallet.fromPhrase(config.mnemonic);
29
+ }
30
+ else if (config.privateKey) {
31
+ wallet = new Wallet(config.privateKey);
32
+ }
33
+ else {
34
+ wallet = Wallet.createRandom();
35
+ }
36
+ // Build XMTP signer adapter
37
+ const signer = {
38
+ getAddress: async () => wallet.address,
39
+ getIdentifier: () => ({
40
+ identifier: wallet.address,
41
+ identifierKind: 0
42
+ }),
43
+ signMessage: async (message) => {
44
+ const sig = await wallet.signMessage(message);
45
+ return getBytes(sig);
46
+ },
47
+ type: "EOA"
48
+ };
49
+ const client = await Client.create(signer, {
50
+ env: config.env || "production"
51
+ });
52
+ console.log(`[OpenAgentClient] Connected as ${wallet.address}`);
53
+ return new OpenAgentClient(client, wallet);
54
+ }
55
+ /**
56
+ * Get the client's wallet address.
57
+ */
58
+ getAddress() {
59
+ return this.wallet.address;
60
+ }
61
+ /**
62
+ * Send a named task to an agent and wait for the response.
63
+ *
64
+ * @param agentAddress - The target agent's wallet address
65
+ * @param method - The task name (e.g. "buy_key", "say_hello")
66
+ * @param params - Task input parameters
67
+ * @param opts - Optional: timeout, payment txHash
68
+ * @returns TaskResult with the response or payment demand
69
+ */
70
+ async sendTask(agentAddress, method, params = {}, opts) {
71
+ const timeout = opts?.timeout ?? 30000;
72
+ // Open DM with the agent
73
+ const conversation = await this.client.conversations.newDmWithIdentifier({
74
+ identifier: agentAddress,
75
+ identifierKind: 0
76
+ });
77
+ // Build JSON-RPC request
78
+ const request = {
79
+ method,
80
+ params,
81
+ id: Date.now()
82
+ };
83
+ // Attach payment proof if provided
84
+ if (opts?.txHash) {
85
+ request.payment = { txHash: opts.txHash };
86
+ }
87
+ // Send as string
88
+ await conversation.send(JSON.stringify(request));
89
+ // Wait for response
90
+ return await this.waitForResponse(conversation, timeout);
91
+ }
92
+ /**
93
+ * Send a plain text message to an agent and wait for the reply.
94
+ *
95
+ * @param agentAddress - The target agent's wallet address
96
+ * @param text - The message text
97
+ * @param timeout - Timeout in ms (default: 30000)
98
+ * @returns TaskResult with the reply
99
+ */
100
+ async chat(agentAddress, text, timeout = 30000) {
101
+ const conversation = await this.client.conversations.newDmWithIdentifier({
102
+ identifier: agentAddress,
103
+ identifierKind: 0
104
+ });
105
+ await conversation.send(text);
106
+ return await this.waitForResponse(conversation, timeout);
107
+ }
108
+ /**
109
+ * Wait for a response message from the agent on a conversation.
110
+ */
111
+ async waitForResponse(conversation, timeout) {
112
+ return new Promise(async (resolve) => {
113
+ const timer = setTimeout(() => {
114
+ resolve({
115
+ success: false,
116
+ error: `Timeout: No response after ${timeout}ms`
117
+ });
118
+ }, timeout);
119
+ try {
120
+ const stream = await conversation.stream();
121
+ for await (const message of stream) {
122
+ // Skip our own messages
123
+ if (message.senderInboxId === this.client.inboxId)
124
+ continue;
125
+ clearTimeout(timer);
126
+ const content = message.content;
127
+ if (typeof content !== 'string') {
128
+ resolve({ success: true, raw: String(content) });
129
+ return;
130
+ }
131
+ // Try to parse as JSON
132
+ try {
133
+ const json = JSON.parse(content);
134
+ // 402 Payment Required
135
+ if (json.type === "PAYMENT_REQUIRED") {
136
+ resolve({
137
+ success: false,
138
+ paymentRequired: json.payment,
139
+ raw: content
140
+ });
141
+ return;
142
+ }
143
+ // JSON-RPC error
144
+ if (json.error) {
145
+ resolve({
146
+ success: false,
147
+ error: json.error.message || JSON.stringify(json.error),
148
+ raw: content
149
+ });
150
+ return;
151
+ }
152
+ // JSON-RPC success
153
+ if (json.result !== undefined) {
154
+ resolve({
155
+ success: true,
156
+ result: json.result,
157
+ raw: content
158
+ });
159
+ return;
160
+ }
161
+ // Generic JSON response
162
+ resolve({ success: true, result: json, raw: content });
163
+ return;
164
+ }
165
+ catch {
166
+ // Plain text response
167
+ resolve({ success: true, result: content, raw: content });
168
+ return;
169
+ }
170
+ }
171
+ }
172
+ catch (err) {
173
+ clearTimeout(timer);
174
+ resolve({
175
+ success: false,
176
+ error: err.message || "Stream error"
177
+ });
178
+ }
179
+ });
180
+ }
181
+ /**
182
+ * Stream all incoming messages across all conversations.
183
+ * Calls the callback for each incoming message (skips own messages).
184
+ * Runs in the background — returns immediately.
185
+ *
186
+ * @param onMessage - Callback receiving (senderAddress, content, conversationId)
187
+ */
188
+ async streamAllMessages(onMessage) {
189
+ // Sync all conversations and messages first
190
+ await this.client.conversations.syncAll();
191
+ const stream = await this.client.conversations.streamAllMessages({
192
+ consentStates: [1 /* ConsentState.Allowed */, 0 /* ConsentState.Unknown */, 2 /* ConsentState.Denied */]
193
+ });
194
+ // Run in background (don't await)
195
+ (async () => {
196
+ try {
197
+ for await (const message of stream) {
198
+ // Skip our own messages
199
+ if (message.senderInboxId === this.client.inboxId)
200
+ continue;
201
+ const content = message.content;
202
+ const conversationId = message.conversationId || '';
203
+ const senderAddress = message.senderInboxId || 'unknown';
204
+ onMessage(senderAddress, String(content), conversationId);
205
+ }
206
+ }
207
+ catch (err) {
208
+ console.error('[OpenAgentClient] Stream error:', err.message);
209
+ }
210
+ })();
211
+ }
212
+ }
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from './skills/payment.js';
7
7
  export * from './skills/discovery.js';
8
8
  export * from './skills/job.js';
9
9
  export * from './registry.js';
10
+ export * from './client.js';
10
11
  export interface OpenAgentConfig {
11
12
  signer?: Signer;
12
13
  mnemonic?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,KAAK,MAAM,EAAoB,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvE,OAAO,EAAY,KAAK,WAAW,IAAI,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEvG,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAE9B,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,GAAG,CAAC,EAAE,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC;CACxC;AAED,qBAAa,SAAS;IAClB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAkB;IAEhC,OAAO;WAMa,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IAoCvE,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACI,GAAG,CAAC,UAAU,EAAE,eAAe;IAItC;;;;OAIG;IACI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC;IAIrE;;OAEG;IACU,KAAK;IAKlB;;;;OAIG;IACU,QAAQ,CACjB,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACpE,OAAO,CAAC,cAAc,CAAC;CAS7B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,KAAK,MAAM,EAAoB,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvE,OAAO,EAAY,KAAK,WAAW,IAAI,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEvG,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAE5B,MAAM,WAAW,eAAe;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,GAAG,CAAC,EAAE,YAAY,GAAG,KAAK,GAAG,OAAO,CAAC;CACxC;AAED,qBAAa,SAAS;IAClB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAkB;IAEhC,OAAO;WAMa,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IAoCvE,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACI,GAAG,CAAC,UAAU,EAAE,eAAe;IAItC;;;;OAIG;IACI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC;IAIrE;;OAEG;IACU,KAAK;IAKlB;;;;OAIG;IACU,QAAQ,CACjB,IAAI,EAAE,mBAAmB,EACzB,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACpE,OAAO,CAAC,cAAc,CAAC;CAS7B"}
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ export * from './skills/payment.js';
8
8
  export * from './skills/discovery.js';
9
9
  export * from './skills/job.js';
10
10
  export * from './registry.js';
11
+ export * from './client.js';
11
12
  export class OpenAgent {
12
13
  agent;
13
14
  config;