@aomi-labs/client 0.1.0 → 0.1.1

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 ADDED
@@ -0,0 +1,272 @@
1
+ # @aomi-labs/client
2
+
3
+ TypeScript client for the Aomi on-chain agent backend. Works in Node.js and browsers.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @aomi-labs/client
9
+ # or
10
+ pnpm add @aomi-labs/client
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ### Low-level client
16
+
17
+ Direct HTTP/SSE access to all backend endpoints.
18
+
19
+ ```ts
20
+ import { AomiClient } from "@aomi-labs/client";
21
+
22
+ const client = new AomiClient({ baseUrl: "https://api.aomi.dev" });
23
+
24
+ const threadId = crypto.randomUUID();
25
+ await client.createThread(threadId);
26
+
27
+ const response = await client.sendMessage(threadId, "What's the price of ETH?");
28
+ console.log(response.messages);
29
+ ```
30
+
31
+ ### Session (high-level)
32
+
33
+ Handles polling, event dispatch, and wallet request management automatically.
34
+
35
+ ```ts
36
+ import { Session } from "@aomi-labs/client";
37
+
38
+ const session = new Session(
39
+ { baseUrl: "https://api.aomi.dev" },
40
+ { namespace: "default" },
41
+ );
42
+
43
+ // Blocking send — polls until the agent finishes responding
44
+ const result = await session.send("Swap 1 ETH for USDC on Uniswap");
45
+ console.log(result.messages);
46
+
47
+ // Listen for wallet signing requests
48
+ session.on("wallet_tx_request", async (req) => {
49
+ const signed = await mySigner.signTransaction(req.payload);
50
+ await session.resolve(req.id, { txHash: signed.hash });
51
+ });
52
+
53
+ session.close();
54
+ ```
55
+
56
+ ### Session API
57
+
58
+ #### Constructor
59
+
60
+ ```ts
61
+ new Session(clientOptions: AomiClientOptions, sessionOptions?: SessionOptions)
62
+ // or pass an existing AomiClient instance:
63
+ new Session(client: AomiClient, sessionOptions?: SessionOptions)
64
+ ```
65
+
66
+ | Option | Default | Description |
67
+ |--------|---------|-------------|
68
+ | `sessionId` | `crypto.randomUUID()` | Thread/session ID |
69
+ | `namespace` | `"default"` | Backend namespace |
70
+ | `publicKey` | — | Wallet address |
71
+ | `apiKey` | — | API key for private namespaces |
72
+ | `userState` | — | Arbitrary user state sent with requests |
73
+ | `pollIntervalMs` | `500` | Polling interval in ms |
74
+ | `logger` | — | Pass `console` for debug output |
75
+
76
+ #### Methods
77
+
78
+ | Method | Description |
79
+ |--------|-------------|
80
+ | `send(message)` | Send a message, wait for completion, return `{ messages, title }` |
81
+ | `sendAsync(message)` | Send without waiting — poll in background, listen via events |
82
+ | `resolve(id, result)` | Resolve a pending wallet request |
83
+ | `reject(id, reason?)` | Reject a pending wallet request |
84
+ | `interrupt()` | Cancel current processing |
85
+ | `close()` | Stop polling, unsubscribe SSE, clean up |
86
+ | `getMessages()` | Current messages |
87
+ | `getTitle()` | Current session title |
88
+ | `getPendingRequests()` | Pending wallet requests |
89
+ | `getIsProcessing()` | Whether the agent is processing |
90
+
91
+ #### Events
92
+
93
+ ```ts
94
+ session.on("wallet_tx_request", (req) => { ... });
95
+ session.on("wallet_eip712_request", (req) => { ... });
96
+ session.on("messages", (msgs) => { ... });
97
+ session.on("processing_start", () => { ... });
98
+ session.on("processing_end", () => { ... });
99
+ session.on("title_changed", ({ title }) => { ... });
100
+ session.on("tool_update", (event) => { ... });
101
+ session.on("tool_complete", (event) => { ... });
102
+ session.on("system_notice", ({ message }) => { ... });
103
+ session.on("system_error", ({ message }) => { ... });
104
+ session.on("error", ({ error }) => { ... });
105
+ session.on("*", ({ type, payload }) => { ... }); // wildcard
106
+ ```
107
+
108
+ `.on()` returns an unsubscribe function:
109
+
110
+ ```ts
111
+ const unsub = session.on("messages", handler);
112
+ unsub(); // stop listening
113
+ ```
114
+
115
+ ## CLI
116
+
117
+ The package includes an `aomi` CLI for scripting and Claude Code skills.
118
+
119
+ ```bash
120
+ npx aomi chat "swap 1 ETH for USDC" # talk to the agent
121
+ npx aomi chat "swap 1 ETH" --verbose # stream tool calls + responses live
122
+ npx aomi log # show full conversation history
123
+ npx aomi tx # list pending + signed txs
124
+ npx aomi sign tx-1 # sign a specific pending tx
125
+ npx aomi status # session info
126
+ npx aomi events # system events
127
+ npx aomi close # clear session
128
+ ```
129
+
130
+ ### Wallet connection
131
+
132
+ Pass `--public-key` so the agent knows your wallet address. This lets it build
133
+ transactions and check your balances:
134
+
135
+ ```bash
136
+ npx aomi chat "send 0 ETH to myself" \
137
+ --public-key 0x5D907BEa404e6F821d467314a9cA07663CF64c9B
138
+ ```
139
+
140
+ The address is persisted in the state file, so subsequent commands in the same
141
+ session don't need it again.
142
+
143
+ ### Transaction flow
144
+
145
+ The backend builds transactions; the CLI persists and signs them:
146
+
147
+ ```
148
+ $ npx aomi chat "swap 1 ETH for USDC on Uniswap" --public-key 0xYourAddr
149
+ ⚡ Wallet request queued: tx-1
150
+ to: 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD
151
+ value: 1000000000000000000
152
+ chain: 1
153
+ Run `aomi tx` to see pending transactions, `aomi sign <id>` to sign.
154
+
155
+ $ npx aomi tx
156
+ Pending (1):
157
+ ⏳ tx-1 to: 0x3fC9...7FAD value: 1000000000000000000 chain: 1
158
+
159
+ $ npx aomi sign tx-1 --private-key 0xac0974...
160
+ Signer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
161
+ ID: tx-1
162
+ Kind: transaction
163
+ To: 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD
164
+ Value: 1000000000000000000
165
+ ✅ Sent! Hash: 0xabc123...
166
+ Backend notified.
167
+
168
+ $ npx aomi tx
169
+ Signed (1):
170
+ ✅ tx-1 hash: 0xabc123... to: 0x3fC9...7FAD value: 1000000000000000000
171
+ ```
172
+
173
+ **EIP-712 signing** is also supported. When the backend requests a typed data
174
+ signature (e.g. for CoW Protocol orders or permit approvals), it shows up as a
175
+ pending tx with `kind: eip712_sign`. `aomi sign` handles both kinds
176
+ automatically:
177
+
178
+ ```
179
+ $ npx aomi tx
180
+ Pending (1):
181
+ ⏳ tx-2 eip712 Sign CoW swap order (2:15:30 PM)
182
+
183
+ $ npx aomi sign tx-2 --private-key 0xac0974...
184
+ Signer: 0xf39Fd...92266
185
+ ID: tx-2
186
+ Kind: eip712_sign
187
+ Desc: Sign CoW swap order
188
+ Type: Order
189
+ ✅ Signed! Signature: 0x1a2b3c4d5e6f...
190
+ Backend notified.
191
+ ```
192
+
193
+ Pending and signed transactions are persisted in `$TMPDIR/aomi-session.json`
194
+ alongside the session pointer, so they survive between CLI invocations.
195
+
196
+ ### Verbose mode & conversation log
197
+
198
+ Use `--verbose` (or `-v`) to see tool calls and agent responses in real-time:
199
+
200
+ ```
201
+ $ npx aomi chat "what's the price of ETH?" --verbose
202
+ ⏳ Processing…
203
+ 🔧 [tool] get_token_price: running
204
+ ✔ [tool] get_token_price → {"price": 2045.67, "symbol": "ETH"}
205
+ 🤖 ETH is currently trading at $2,045.67.
206
+ ✅ Done
207
+ ```
208
+
209
+ Without `--verbose`, only the final agent message is printed.
210
+
211
+ Use `aomi log` to replay the full conversation with all messages and tool results:
212
+
213
+ ```
214
+ $ npx aomi log
215
+ 10:30:15 AM 👤 You: what's the price of ETH?
216
+ 10:30:16 AM 🤖 Agent: Let me check the current on-chain context for you.
217
+ 10:30:16 AM 🔧 [Current ETH price] {"price": 2045.67, "symbol": "ETH"}
218
+ 10:30:17 AM 🤖 Agent: ETH is currently trading at $2,045.67.
219
+
220
+ — 4 messages —
221
+ ```
222
+
223
+ ### Options
224
+
225
+ All config can be passed as flags (which take priority over env vars):
226
+
227
+ | Flag | Env Variable | Default | Description |
228
+ |------|-------------|---------|-------------|
229
+ | `--backend-url` | `AOMI_BASE_URL` | `https://api.aomi.dev` | Backend URL |
230
+ | `--api-key` | `AOMI_API_KEY` | — | API key for non-default namespaces |
231
+ | `--namespace` | `AOMI_NAMESPACE` | `default` | Namespace |
232
+ | `--public-key` | `AOMI_PUBLIC_KEY` | — | Wallet address (tells agent your wallet) |
233
+ | `--private-key` | `PRIVATE_KEY` | — | Hex private key for `aomi sign` |
234
+ | `--rpc-url` | `CHAIN_RPC_URL` | — | RPC URL for transaction submission |
235
+ | `--verbose`, `-v` | — | — | Stream tool calls and agent responses live |
236
+
237
+ ```bash
238
+ # Use a custom backend
239
+ npx aomi chat "hello" --backend-url https://my-backend.example.com
240
+
241
+ # Full signing flow with all flags
242
+ npx aomi chat "send 0.1 ETH to vitalik.eth" \
243
+ --public-key 0xYourAddress \
244
+ --api-key sk-abc123 \
245
+ --namespace my-agent
246
+ npx aomi sign tx-1 \
247
+ --private-key 0xYourPrivateKey \
248
+ --rpc-url https://eth.llamarpc.com
249
+ ```
250
+
251
+ ### How state works
252
+
253
+ The CLI is **not** a long-running process — each command starts, runs, and
254
+ exits. Conversation history lives on the backend. Between invocations, the CLI
255
+ persists a small JSON file to `$TMPDIR/aomi-session.json`:
256
+
257
+ | Field | Purpose |
258
+ |-------|---------|
259
+ | `sessionId` | Which conversation to continue |
260
+ | `publicKey` | Wallet address (from `--public-key`) |
261
+ | `pendingTxs` | Unsigned transactions waiting for `aomi sign <id>` |
262
+ | `signedTxs` | Completed transactions with hashes/signatures |
263
+
264
+ ```
265
+ $ npx aomi chat "hello" # creates session, saves sessionId
266
+ $ npx aomi chat "swap 1 ETH" # reuses session, queues tx-1 if wallet request arrives
267
+ $ npx aomi sign tx-1 # signs tx-1, moves to signedTxs, notifies backend
268
+ $ npx aomi tx # shows all txs
269
+ $ npx aomi close # wipes state file
270
+ ```
271
+
272
+ The state file lives in your OS temp directory and gets cleaned up on reboot.