@circuitorg/agent-sdk 1.1.7 β 1.1.8
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 +158 -244
- package/index.d.ts +266 -4
- package/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
# Circuit Agent SDK - Typescript
|
|
2
2
|
|
|
3
|
-
> **Clean, type-safe TypeScript SDK for building cross-chain agents on the circuit platform**
|
|
4
3
|
|
|
5
|
-
A TypeScript SDK for building automated agents to deploy on Circuit. Features
|
|
4
|
+
A TypeScript SDK for building automated agents to deploy on Circuit. Features **2 low-level core methods** for maximum flexibility, plus **built-in platform integrations** for common on-chain operationsβall with full type safety.
|
|
6
5
|
|
|
7
6
|
> **π‘ Best used with [Circuit Agents CLI](https://github.com/circuitorg/agents-cli)** - Deploy, manage, and test your agents with ease
|
|
8
7
|
|
|
8
|
+
## π Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Features](#-features)
|
|
11
|
+
- [Quick Start](#-quick-start)
|
|
12
|
+
- [Core SDK API](#-core-sdk-api-only-2-methods) - Low-level transaction & event logging methods
|
|
13
|
+
- [Cross-Chain Swaps with Swidge](#-cross-chain-swaps-with-swidge) - Token swaps & bridges
|
|
14
|
+
- [Polymarket Prediction Markets](#-polymarket-prediction-markets) - Trading integration
|
|
15
|
+
- [Session Memory Storage](#-session-memory-storage) - State management
|
|
16
|
+
- [Examples](#-examples)
|
|
17
|
+
|
|
9
18
|
## β¨ Features
|
|
10
19
|
|
|
11
|
-
- **π―
|
|
20
|
+
- **π― Low-Level Core API**: 2 foundational methods (`sendLog()`, `signAndSend()`) for sending custom transactions
|
|
12
21
|
- **π Type Safety**: Network parameter determines valid request shapes automatically
|
|
13
22
|
- **π Cross-Chain**: Unified interface for EVM and Solana networks
|
|
14
23
|
- **π Cross-Chain Swaps**: Built-in Swidge integration for seamless token swaps and bridges
|
|
15
24
|
- **π Polymarket Integration**: Trade prediction markets with `sdk.polymarket.*` methods
|
|
25
|
+
- **πΎ Session Memory**: Key-value storage with `sdk.memory.*` methods for maintaining state
|
|
16
26
|
|
|
17
27
|
## π Quick Start
|
|
18
28
|
### Install the SDK
|
|
@@ -38,6 +48,8 @@ const sdk = new AgentSdk({
|
|
|
38
48
|
|
|
39
49
|
## π― Core SDK API (Only 2 Methods!)
|
|
40
50
|
|
|
51
|
+
> **Low-level building blocks** for direct blockchain interaction. Use these for maximum flexibility, or leverage our higher-level integrations (Swidge, Polymarket, Memory) for common operations.
|
|
52
|
+
|
|
41
53
|
### 1. Add Logs to Timeline
|
|
42
54
|
|
|
43
55
|
```typescript
|
|
@@ -86,13 +98,13 @@ await sdk.signAndSend({
|
|
|
86
98
|
```
|
|
87
99
|
|
|
88
100
|
|
|
89
|
-
## π Cross-Chain Swaps with Swidge
|
|
101
|
+
## π Cross-Chain Swaps and Bridging with Swidge
|
|
90
102
|
|
|
91
|
-
|
|
103
|
+
> **High-level abstraction** built on core SDK methods. Simplifies cross-chain token operations with a quote-and-execute pattern.
|
|
92
104
|
|
|
93
|
-
Swidge provides a unified interface that handles both **swapping** (exchanging tokens within the same network) and **bridging** (moving tokens across different networks) through a single
|
|
105
|
+
The SDK includes built-in Swidge integration for seamless cross-chain token swaps and bridges. Swidge provides a unified interface that handles both **swapping** (exchanging tokens within the same network) and **bridging** (moving tokens across different networks) through a single API. Whether you're doing a simple token swap on Ethereum or bridging assets across chains, the same pattern works for everything.
|
|
94
106
|
|
|
95
|
-
###
|
|
107
|
+
### Cross-Chain Swaps & Bridges
|
|
96
108
|
|
|
97
109
|
#### Get a Quote
|
|
98
110
|
|
|
@@ -187,152 +199,16 @@ if (quote.success && quote.data) {
|
|
|
187
199
|
}
|
|
188
200
|
```
|
|
189
201
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
#### `sdk.swidge.quote(request: SwidgeQuoteRequest): Promise<SwidgeQuoteResponse>`
|
|
193
|
-
|
|
194
|
-
Get pricing and routing information for token swaps between networks or within the same network.
|
|
195
|
-
|
|
196
|
-
**Parameters:**
|
|
197
|
-
```typescript
|
|
198
|
-
{
|
|
199
|
-
from: { network: SwidgeNetwork, address: string },
|
|
200
|
-
to: { network: SwidgeNetwork, address: string },
|
|
201
|
-
amount: string, // Amount in token's smallest unit
|
|
202
|
-
fromToken?: string, // Source token contract (omit for native tokens)
|
|
203
|
-
toToken?: string, // Destination token contract (omit for native tokens)
|
|
204
|
-
slippage?: string, // Slippage tolerance % (default: "0.5")
|
|
205
|
-
priceImpact?: string // Max price impact % (default: "0.5")
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
**Returns:**
|
|
210
|
-
```typescript
|
|
211
|
-
{
|
|
212
|
-
success: boolean,
|
|
213
|
-
data?: {
|
|
214
|
-
engine: "relay",
|
|
215
|
-
assetSend: {
|
|
216
|
-
network: SwidgeNetwork,
|
|
217
|
-
address: string,
|
|
218
|
-
token: string | null,
|
|
219
|
-
amount: string,
|
|
220
|
-
amountFormatted: string,
|
|
221
|
-
amountUsd: string,
|
|
222
|
-
// ... additional fields
|
|
223
|
-
},
|
|
224
|
-
assetReceive: {
|
|
225
|
-
network: SwidgeNetwork,
|
|
226
|
-
address: string,
|
|
227
|
-
token: string | null,
|
|
228
|
-
amount: string,
|
|
229
|
-
amountFormatted: string,
|
|
230
|
-
amountUsd: string,
|
|
231
|
-
// ... additional fields
|
|
232
|
-
},
|
|
233
|
-
priceImpact: {
|
|
234
|
-
usd?: string,
|
|
235
|
-
percentage?: string
|
|
236
|
-
},
|
|
237
|
-
fees: Array<{
|
|
238
|
-
name: string,
|
|
239
|
-
amount?: string,
|
|
240
|
-
amountFormatted?: string,
|
|
241
|
-
amountUsd?: string
|
|
242
|
-
}>,
|
|
243
|
-
steps: Array<SwidgeUnsignedStep> // Transaction steps to execute
|
|
244
|
-
},
|
|
245
|
-
error?: string,
|
|
246
|
-
errorDetails?: {
|
|
247
|
-
message: string,
|
|
248
|
-
status?: number,
|
|
249
|
-
statusText?: string
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Error Handling with QUOTE_RESULT:**
|
|
255
|
-
|
|
256
|
-
The SDK exports a `QUOTE_RESULT` constant that provides type-safe error checking with full IntelliSense support:
|
|
257
|
-
|
|
258
|
-
```typescript
|
|
259
|
-
import { QUOTE_RESULT } from "@circuitorg/agent-sdk";
|
|
260
|
-
|
|
261
|
-
// Use QUOTE_RESULT constants instead of hardcoded strings
|
|
262
|
-
if (quote.error === QUOTE_RESULT.WALLET_NOT_FOUND) {
|
|
263
|
-
// Handle wallet not found
|
|
264
|
-
} else if (quote.error === QUOTE_RESULT.WALLET_MISMATCH) {
|
|
265
|
-
// Handle wallet mismatch
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
**Possible Error Responses:**
|
|
270
|
-
- `QUOTE_RESULT.FOUND` - Success case (not an error)
|
|
271
|
-
- `QUOTE_RESULT.NO_QUOTE_PROVIDED` - Generic API error
|
|
272
|
-
- `QUOTE_RESULT.WALLET_NOT_FOUND` - Wallet address not found
|
|
273
|
-
- `QUOTE_RESULT.WALLET_MISMATCH` - From wallet does not match session wallet
|
|
274
|
-
|
|
275
|
-
#### `sdk.swidge.execute(quoteData: SwidgeExecuteRequest): Promise<SwidgeExecuteResponse>`
|
|
276
|
-
|
|
277
|
-
Execute a cross-chain swap or bridge using a complete quote from `sdk.swidge.quote()`.
|
|
278
|
-
|
|
279
|
-
Pass the entire `quote.data` object returned from `quote()` - the SDK handles all transaction signing, broadcasting, and cross-chain coordination.
|
|
280
|
-
|
|
281
|
-
**Parameters:**
|
|
282
|
-
```typescript
|
|
283
|
-
// The complete quote.data object from sdk.swidge.quote()
|
|
284
|
-
{
|
|
285
|
-
engine: "relay",
|
|
286
|
-
assetSend: SwidgeQuoteAsset,
|
|
287
|
-
assetReceive: SwidgeQuoteAsset,
|
|
288
|
-
priceImpact: SwidgePriceImpact,
|
|
289
|
-
fees: SwidgeFee[],
|
|
290
|
-
steps: SwidgeUnsignedStep[] // Contains transaction details for each step
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Returns:**
|
|
295
|
-
```typescript
|
|
296
|
-
{
|
|
297
|
-
success: boolean,
|
|
298
|
-
data?: {
|
|
299
|
-
status: "success" | "failure" | "refund" | "delayed",
|
|
300
|
-
in: {
|
|
301
|
-
network: string,
|
|
302
|
-
txs: string[] // Transaction hashes for sending side
|
|
303
|
-
},
|
|
304
|
-
out: {
|
|
305
|
-
network: string,
|
|
306
|
-
txs: string[] // Transaction hashes for receiving side
|
|
307
|
-
},
|
|
308
|
-
lastUpdated: number // Timestamp of last status update
|
|
309
|
-
},
|
|
310
|
-
error?: string,
|
|
311
|
-
errorDetails?: {
|
|
312
|
-
message: string,
|
|
313
|
-
status?: number,
|
|
314
|
-
statusText?: string
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
**Execution Flow:**
|
|
320
|
-
1. SDK signs and broadcasts transactions from the `steps` array
|
|
321
|
-
2. Monitors cross-chain execution progress
|
|
322
|
-
3. Returns final status once complete (never returns "pending" or "waiting")
|
|
202
|
+
## π Polymarket Prediction Markets
|
|
323
203
|
|
|
324
|
-
**
|
|
325
|
-
- `"success"` - All transactions completed successfully
|
|
326
|
-
- `"failure"` - One or more transactions failed
|
|
327
|
-
- `"refund"` - Transaction was refunded (e.g., due to timeout or failure)
|
|
328
|
-
- `"delayed"` - Transaction is taking longer than expected but still processing
|
|
204
|
+
> **High-level abstraction** built on core SDK methods. Simplifies prediction market trading on Polygon.
|
|
329
205
|
|
|
206
|
+
> **Note:** Due to polymarket accepting buys and sells with different decimal precision, you may end up with dust positions when trying to sell to close out a position.
|
|
330
207
|
|
|
331
|
-
## π Polymarket Prediction Markets
|
|
332
208
|
|
|
333
209
|
The SDK includes built-in Polymarket integration for trading prediction markets on Polygon.
|
|
334
210
|
|
|
335
|
-
###
|
|
211
|
+
### Polymarket Trading
|
|
336
212
|
|
|
337
213
|
#### Get Positions
|
|
338
214
|
|
|
@@ -391,7 +267,11 @@ const redemption = await sdk.polymarket.redeemPositions();
|
|
|
391
267
|
if (redemption.success && redemption.data) {
|
|
392
268
|
for (const result of redemption.data) {
|
|
393
269
|
if (result.success) {
|
|
394
|
-
|
|
270
|
+
if (result.position) {
|
|
271
|
+
console.log(`β
Redeemed: ${result.position.question}`);
|
|
272
|
+
} else {
|
|
273
|
+
console.log(`β
Unwrapped collateral`);
|
|
274
|
+
}
|
|
395
275
|
console.log(` TX: ${result.transactionHash}`);
|
|
396
276
|
}
|
|
397
277
|
}
|
|
@@ -403,102 +283,6 @@ const specificRedemption = await sdk.polymarket.redeemPositions({
|
|
|
403
283
|
});
|
|
404
284
|
```
|
|
405
285
|
|
|
406
|
-
### Polymarket API Reference
|
|
407
|
-
|
|
408
|
-
#### `sdk.polymarket.positions(): Promise<PolymarketPositionsResponse>`
|
|
409
|
-
|
|
410
|
-
Get all current positions for the session wallet.
|
|
411
|
-
|
|
412
|
-
**Returns:**
|
|
413
|
-
```typescript
|
|
414
|
-
{
|
|
415
|
-
success: boolean,
|
|
416
|
-
data?: {
|
|
417
|
-
totalValue: number,
|
|
418
|
-
positions: Array<{
|
|
419
|
-
contractAddress: string,
|
|
420
|
-
tokenId: string,
|
|
421
|
-
question: string,
|
|
422
|
-
outcome: string,
|
|
423
|
-
formattedShares: string,
|
|
424
|
-
shares: string,
|
|
425
|
-
valueUsd: string,
|
|
426
|
-
priceUsd: string,
|
|
427
|
-
averagePriceUsd: string,
|
|
428
|
-
pnlUsd: string,
|
|
429
|
-
pnlPercent: string,
|
|
430
|
-
isRedeemable: boolean,
|
|
431
|
-
endDate: string,
|
|
432
|
-
// ... additional fields
|
|
433
|
-
}>
|
|
434
|
-
},
|
|
435
|
-
error?: string,
|
|
436
|
-
errorDetails?: { message: string, status?: number, statusText?: string }
|
|
437
|
-
}
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
#### `sdk.polymarket.marketOrder(request): Promise<PolymarketMarketOrderResponse>`
|
|
441
|
-
|
|
442
|
-
Place a buy or sell market order.
|
|
443
|
-
|
|
444
|
-
β οΈ **Important**: The `size` parameter meaning differs by order side:
|
|
445
|
-
- **BUY**: `size` is the USD amount to spend (e.g., 10 = $10 worth of shares)
|
|
446
|
-
- **SELL**: `size` is the number of shares/tokens to sell (e.g., 10 = 10 shares)
|
|
447
|
-
|
|
448
|
-
**Parameters:**
|
|
449
|
-
```typescript
|
|
450
|
-
{
|
|
451
|
-
tokenId: string, // Market token ID for the position
|
|
452
|
-
size: number, // For BUY: USD amount. For SELL: Number of shares
|
|
453
|
-
side: "BUY" | "SELL"
|
|
454
|
-
}
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
**Returns:**
|
|
458
|
-
```typescript
|
|
459
|
-
{
|
|
460
|
-
success: boolean,
|
|
461
|
-
data?: {
|
|
462
|
-
success: boolean, // Whether the order was successfully submitted
|
|
463
|
-
orderInfo: {
|
|
464
|
-
orderId: string,
|
|
465
|
-
side: string,
|
|
466
|
-
size: string,
|
|
467
|
-
priceUsd: string,
|
|
468
|
-
totalPriceUsd: string,
|
|
469
|
-
txHashes: string[]
|
|
470
|
-
}
|
|
471
|
-
},
|
|
472
|
-
error?: string,
|
|
473
|
-
errorDetails?: { message: string, status?: number, statusText?: string }
|
|
474
|
-
}
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
#### `sdk.polymarket.redeemPositions(request?): Promise<PolymarketRedeemPositionsResponse>`
|
|
478
|
-
|
|
479
|
-
Redeem settled positions to claim winnings.
|
|
480
|
-
|
|
481
|
-
**Parameters (optional):**
|
|
482
|
-
```typescript
|
|
483
|
-
{
|
|
484
|
-
tokenIds?: string[] // Specific token IDs to redeem (default: all redeemable positions)
|
|
485
|
-
}
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
**Returns:**
|
|
489
|
-
```typescript
|
|
490
|
-
{
|
|
491
|
-
success: boolean,
|
|
492
|
-
data?: Array<{
|
|
493
|
-
success: boolean,
|
|
494
|
-
position: { /* Full position details */ },
|
|
495
|
-
transactionHash: string | null
|
|
496
|
-
}>,
|
|
497
|
-
error?: string,
|
|
498
|
-
errorDetails?: { message: string, status?: number, statusText?: string }
|
|
499
|
-
}
|
|
500
|
-
```
|
|
501
|
-
|
|
502
286
|
### Complete Polymarket Example
|
|
503
287
|
|
|
504
288
|
```typescript
|
|
@@ -566,6 +350,136 @@ const stopFunction: StopFunctionContract = async (request) => {
|
|
|
566
350
|
};
|
|
567
351
|
```
|
|
568
352
|
|
|
353
|
+
## πΎ Session Memory Storage
|
|
354
|
+
|
|
355
|
+
> **High-level abstraction** built on core SDK methods. Provides key-value storage for maintaining state across execution cycles without external databases.
|
|
356
|
+
|
|
357
|
+
Store and retrieve data for your agent's session with simple get/set/delete/list operations. Memory is **automatically scoped to your session ID** - each session has isolated storage that persists across execution cycles.
|
|
358
|
+
|
|
359
|
+
### Memory Operations
|
|
360
|
+
|
|
361
|
+
#### Set a Value
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
// Store user preferences
|
|
365
|
+
const result = await sdk.memory.set("lastSwapNetwork", "ethereum:42161");
|
|
366
|
+
|
|
367
|
+
if (result.success && result.data) {
|
|
368
|
+
console.log(`Stored key: ${result.data.key}`);
|
|
369
|
+
} else {
|
|
370
|
+
console.error(`Failed to store: ${result.error}`);
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
#### Get a Value
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// Retrieve stored preferences
|
|
378
|
+
const result = await sdk.memory.get("lastSwapNetwork");
|
|
379
|
+
|
|
380
|
+
if (result.success && result.data) {
|
|
381
|
+
console.log(`Network: ${result.data.value}`);
|
|
382
|
+
} else {
|
|
383
|
+
console.log(`Key not found: ${result.error}`);
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
#### Delete a Value
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
// Clean up temporary data
|
|
391
|
+
const result = await sdk.memory.delete("tempSwapQuote");
|
|
392
|
+
|
|
393
|
+
if (result.success && result.data) {
|
|
394
|
+
console.log(`Deleted key: ${result.data.key}`);
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### List All Keys
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
// List all stored keys
|
|
402
|
+
const result = await sdk.memory.list();
|
|
403
|
+
|
|
404
|
+
if (result.success && result.data) {
|
|
405
|
+
console.log(`Found ${result.data.count} keys:`);
|
|
406
|
+
result.data.keys.forEach(key => console.log(` - ${key}`));
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Complete Memory Example
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
414
|
+
const sdk = new AgentSdk({ sessionId: request.sessionId });
|
|
415
|
+
|
|
416
|
+
try {
|
|
417
|
+
// Check if this is a first run by looking for a stored counter
|
|
418
|
+
const counterResult = await sdk.memory.get("executionCount");
|
|
419
|
+
|
|
420
|
+
let count = 0;
|
|
421
|
+
if (counterResult.success && counterResult.data) {
|
|
422
|
+
count = parseInt(counterResult.data.value);
|
|
423
|
+
await sdk.sendLog({
|
|
424
|
+
type: "observe",
|
|
425
|
+
shortMessage: `Execution #${count + 1} - Welcome back!`
|
|
426
|
+
});
|
|
427
|
+
} else {
|
|
428
|
+
await sdk.sendLog({
|
|
429
|
+
type: "observe",
|
|
430
|
+
shortMessage: "First execution - initializing..."
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Store some session data
|
|
435
|
+
await sdk.memory.set("executionCount", String(count + 1));
|
|
436
|
+
await sdk.memory.set("lastRunTimestamp", Date.now().toString());
|
|
437
|
+
await sdk.memory.set("userPreferences", JSON.stringify({
|
|
438
|
+
network: "ethereum:42161",
|
|
439
|
+
slippage: "2.0"
|
|
440
|
+
}));
|
|
441
|
+
|
|
442
|
+
// List all stored keys
|
|
443
|
+
const listResult = await sdk.memory.list();
|
|
444
|
+
if (listResult.success && listResult.data) {
|
|
445
|
+
await sdk.sendLog({
|
|
446
|
+
type: "observe",
|
|
447
|
+
shortMessage: `Stored ${listResult.data.count} keys: ${listResult.data.keys.join(", ")}`
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return { success: true };
|
|
452
|
+
} catch (error) {
|
|
453
|
+
await sdk.sendLog({
|
|
454
|
+
type: "error",
|
|
455
|
+
shortMessage: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
456
|
+
});
|
|
457
|
+
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
const stopFunction: StopFunctionContract = async (request) => {
|
|
462
|
+
const sdk = new AgentSdk({ sessionId: request.sessionId });
|
|
463
|
+
|
|
464
|
+
try {
|
|
465
|
+
// Clean up temporary data on stop
|
|
466
|
+
const listResult = await sdk.memory.list();
|
|
467
|
+
if (listResult.success && listResult.data) {
|
|
468
|
+
// Delete all temp keys
|
|
469
|
+
for (const key of listResult.data.keys) {
|
|
470
|
+
if (key.startsWith("temp_")) {
|
|
471
|
+
await sdk.memory.delete(key);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return { success: true };
|
|
477
|
+
} catch (error) {
|
|
478
|
+
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
```
|
|
482
|
+
|
|
569
483
|
|
|
570
484
|
## π§ Examples
|
|
571
485
|
|
package/index.d.ts
CHANGED
|
@@ -393,6 +393,7 @@ declare const PolymarketPositionSchema: z.ZodObject<{
|
|
|
393
393
|
priceUsd: z.ZodString;
|
|
394
394
|
averagePriceUsd: z.ZodString;
|
|
395
395
|
isRedeemable: z.ZodBoolean;
|
|
396
|
+
isNegativeRisk: z.ZodBoolean;
|
|
396
397
|
imageUrl: z.ZodString;
|
|
397
398
|
initialValue: z.ZodString;
|
|
398
399
|
pnlUsd: z.ZodString;
|
|
@@ -429,6 +430,7 @@ declare const PolymarketPositionsResponseSchema: z.ZodObject<{
|
|
|
429
430
|
priceUsd: z.ZodString;
|
|
430
431
|
averagePriceUsd: z.ZodString;
|
|
431
432
|
isRedeemable: z.ZodBoolean;
|
|
433
|
+
isNegativeRisk: z.ZodBoolean;
|
|
432
434
|
imageUrl: z.ZodString;
|
|
433
435
|
initialValue: z.ZodString;
|
|
434
436
|
pnlUsd: z.ZodString;
|
|
@@ -469,7 +471,7 @@ declare const PolymarketRedeemPositionsResponseSchema: z.ZodObject<{
|
|
|
469
471
|
success: z.ZodBoolean;
|
|
470
472
|
data: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
471
473
|
success: z.ZodBoolean;
|
|
472
|
-
position: z.ZodObject<{
|
|
474
|
+
position: z.ZodNullable<z.ZodObject<{
|
|
473
475
|
contractAddress: z.ZodString;
|
|
474
476
|
tokenId: z.ZodNullable<z.ZodString>;
|
|
475
477
|
decimals: z.ZodNumber;
|
|
@@ -482,6 +484,7 @@ declare const PolymarketRedeemPositionsResponseSchema: z.ZodObject<{
|
|
|
482
484
|
priceUsd: z.ZodString;
|
|
483
485
|
averagePriceUsd: z.ZodString;
|
|
484
486
|
isRedeemable: z.ZodBoolean;
|
|
487
|
+
isNegativeRisk: z.ZodBoolean;
|
|
485
488
|
imageUrl: z.ZodString;
|
|
486
489
|
initialValue: z.ZodString;
|
|
487
490
|
pnlUsd: z.ZodString;
|
|
@@ -489,7 +492,7 @@ declare const PolymarketRedeemPositionsResponseSchema: z.ZodObject<{
|
|
|
489
492
|
pnlRealizedUsd: z.ZodString;
|
|
490
493
|
pnlRealizedPercent: z.ZodString;
|
|
491
494
|
endDate: z.ZodString;
|
|
492
|
-
}, z.core.$strip
|
|
495
|
+
}, z.core.$strip>>;
|
|
493
496
|
transactionHash: z.ZodNullable<z.ZodString>;
|
|
494
497
|
}, z.core.$strip>>>;
|
|
495
498
|
error: z.ZodOptional<z.ZodString>;
|
|
@@ -506,6 +509,107 @@ type PolymarketPositionsResponse = z.infer<typeof PolymarketPositionsResponseSch
|
|
|
506
509
|
type PolymarketMarketOrderResponse = z.infer<typeof PolymarketMarketOrderResponseSchema>;
|
|
507
510
|
type PolymarketRedeemPositionsResponse = z.infer<typeof PolymarketRedeemPositionsResponseSchema>;
|
|
508
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Memory type definitions for agent session storage
|
|
514
|
+
*
|
|
515
|
+
* Memory operations provide key-value storage scoped to the current agent session.
|
|
516
|
+
* All keys are automatically namespaced by agentId and sessionId.
|
|
517
|
+
*/
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Request to set a key-value pair in memory
|
|
521
|
+
*/
|
|
522
|
+
declare const MemorySetRequestSchema: z.ZodObject<{
|
|
523
|
+
key: z.ZodString;
|
|
524
|
+
value: z.ZodString;
|
|
525
|
+
}, z.core.$strip>;
|
|
526
|
+
/**
|
|
527
|
+
* Request to get a value by key from memory
|
|
528
|
+
*/
|
|
529
|
+
declare const MemoryGetRequestSchema: z.ZodObject<{
|
|
530
|
+
key: z.ZodString;
|
|
531
|
+
}, z.core.$strip>;
|
|
532
|
+
/**
|
|
533
|
+
* Request to delete a key from memory
|
|
534
|
+
*/
|
|
535
|
+
declare const MemoryDeleteRequestSchema: z.ZodObject<{
|
|
536
|
+
key: z.ZodString;
|
|
537
|
+
}, z.core.$strip>;
|
|
538
|
+
/**
|
|
539
|
+
* Request to list all keys in memory (no parameters needed)
|
|
540
|
+
*/
|
|
541
|
+
declare const MemoryListRequestSchema: z.ZodObject<{}, z.core.$strip>;
|
|
542
|
+
/**
|
|
543
|
+
* Memory set response wrapper
|
|
544
|
+
*/
|
|
545
|
+
declare const MemorySetResponseSchema: z.ZodObject<{
|
|
546
|
+
success: z.ZodBoolean;
|
|
547
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
548
|
+
key: z.ZodString;
|
|
549
|
+
}, z.core.$strip>>;
|
|
550
|
+
error: z.ZodOptional<z.ZodString>;
|
|
551
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
552
|
+
message: z.ZodString;
|
|
553
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
554
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
555
|
+
}, z.core.$strip>>;
|
|
556
|
+
}, z.core.$strip>;
|
|
557
|
+
/**
|
|
558
|
+
* Memory get response wrapper
|
|
559
|
+
*/
|
|
560
|
+
declare const MemoryGetResponseSchema: z.ZodObject<{
|
|
561
|
+
success: z.ZodBoolean;
|
|
562
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
563
|
+
key: z.ZodString;
|
|
564
|
+
value: z.ZodString;
|
|
565
|
+
}, z.core.$strip>>;
|
|
566
|
+
error: z.ZodOptional<z.ZodString>;
|
|
567
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
568
|
+
message: z.ZodString;
|
|
569
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
570
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
571
|
+
}, z.core.$strip>>;
|
|
572
|
+
}, z.core.$strip>;
|
|
573
|
+
/**
|
|
574
|
+
* Memory delete response wrapper
|
|
575
|
+
*/
|
|
576
|
+
declare const MemoryDeleteResponseSchema: z.ZodObject<{
|
|
577
|
+
success: z.ZodBoolean;
|
|
578
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
579
|
+
key: z.ZodString;
|
|
580
|
+
}, z.core.$strip>>;
|
|
581
|
+
error: z.ZodOptional<z.ZodString>;
|
|
582
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
583
|
+
message: z.ZodString;
|
|
584
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
585
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
586
|
+
}, z.core.$strip>>;
|
|
587
|
+
}, z.core.$strip>;
|
|
588
|
+
/**
|
|
589
|
+
* Memory list response wrapper
|
|
590
|
+
*/
|
|
591
|
+
declare const MemoryListResponseSchema: z.ZodObject<{
|
|
592
|
+
success: z.ZodBoolean;
|
|
593
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
594
|
+
keys: z.ZodArray<z.ZodString>;
|
|
595
|
+
count: z.ZodNumber;
|
|
596
|
+
}, z.core.$strip>>;
|
|
597
|
+
error: z.ZodOptional<z.ZodString>;
|
|
598
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
599
|
+
message: z.ZodString;
|
|
600
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
601
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
602
|
+
}, z.core.$strip>>;
|
|
603
|
+
}, z.core.$strip>;
|
|
604
|
+
type MemorySetRequest = z.infer<typeof MemorySetRequestSchema>;
|
|
605
|
+
type MemoryGetRequest = z.infer<typeof MemoryGetRequestSchema>;
|
|
606
|
+
type MemoryDeleteRequest = z.infer<typeof MemoryDeleteRequestSchema>;
|
|
607
|
+
type MemoryListRequest = z.infer<typeof MemoryListRequestSchema>;
|
|
608
|
+
type MemorySetResponse = z.infer<typeof MemorySetResponseSchema>;
|
|
609
|
+
type MemoryGetResponse = z.infer<typeof MemoryGetResponseSchema>;
|
|
610
|
+
type MemoryDeleteResponse = z.infer<typeof MemoryDeleteResponseSchema>;
|
|
611
|
+
type MemoryListResponse = z.infer<typeof MemoryListResponseSchema>;
|
|
612
|
+
|
|
509
613
|
/**
|
|
510
614
|
* Main AgentSdk class with simplified API surface
|
|
511
615
|
*/
|
|
@@ -775,6 +879,136 @@ declare class AgentSdk {
|
|
|
775
879
|
*/
|
|
776
880
|
execute: (executeQuote: SwidgeExecuteRequest) => Promise<SwidgeExecuteResponse>;
|
|
777
881
|
};
|
|
882
|
+
/**
|
|
883
|
+
* πΎ Memory: Session-scoped key-value storage
|
|
884
|
+
*
|
|
885
|
+
* Store and retrieve data for your agent's session. All keys are automatically
|
|
886
|
+
* namespaced by agentId and sessionId - perfect for maintaining state across
|
|
887
|
+
* execution cycles.
|
|
888
|
+
*/
|
|
889
|
+
readonly memory: {
|
|
890
|
+
/**
|
|
891
|
+
* Set a key-value pair in session memory
|
|
892
|
+
*
|
|
893
|
+
* Store a string value with a unique key. The key is automatically scoped to your
|
|
894
|
+
* agent and session, so you don't need to worry about collisions.
|
|
895
|
+
*
|
|
896
|
+
* @param key Unique identifier for the value (1-255 characters)
|
|
897
|
+
* @param value String value to store
|
|
898
|
+
* @returns Promise with success status and the stored key
|
|
899
|
+
*
|
|
900
|
+
* @example
|
|
901
|
+
* ```ts
|
|
902
|
+
* // Store user preferences
|
|
903
|
+
* const result = await sdk.memory.set("lastSwapNetwork", "ethereum:42161");
|
|
904
|
+
*
|
|
905
|
+
* if (result.success && result.data) {
|
|
906
|
+
* console.log(`Stored key: ${result.data.key}`);
|
|
907
|
+
* } else {
|
|
908
|
+
* console.error(`Failed to store: ${result.error}`);
|
|
909
|
+
* }
|
|
910
|
+
* ```
|
|
911
|
+
*
|
|
912
|
+
* **Input**: `{ key: string, value: string }`
|
|
913
|
+
*
|
|
914
|
+
* **Output**: `MemorySetResponse`
|
|
915
|
+
* - `success` (bool): Whether the operation succeeded
|
|
916
|
+
* - `data` (object | undefined): Present on success
|
|
917
|
+
* - `key` (string): The key that was set
|
|
918
|
+
* - `error` (string | undefined): Error message on failure
|
|
919
|
+
* - `errorDetails` (object | undefined): Detailed error info on failure
|
|
920
|
+
*/
|
|
921
|
+
set: (key: string, value: string) => Promise<MemorySetResponse>;
|
|
922
|
+
/**
|
|
923
|
+
* Get a value by key from session memory
|
|
924
|
+
*
|
|
925
|
+
* Retrieve a previously stored value. Returns an error if the key doesn't exist.
|
|
926
|
+
*
|
|
927
|
+
* @param key The key to retrieve
|
|
928
|
+
* @returns Promise with the key and its value, or error details
|
|
929
|
+
*
|
|
930
|
+
* @example
|
|
931
|
+
* ```ts
|
|
932
|
+
* // Retrieve stored preferences
|
|
933
|
+
* const result = await sdk.memory.get("lastSwapNetwork");
|
|
934
|
+
*
|
|
935
|
+
* if (result.success && result.data) {
|
|
936
|
+
* console.log(`Network: ${result.data.value}`);
|
|
937
|
+
* } else {
|
|
938
|
+
* console.log(`Key not found: ${result.error}`);
|
|
939
|
+
* }
|
|
940
|
+
* ```
|
|
941
|
+
*
|
|
942
|
+
* **Input**: `key: string`
|
|
943
|
+
*
|
|
944
|
+
* **Output**: `MemoryGetResponse`
|
|
945
|
+
* - `success` (bool): Whether the operation succeeded
|
|
946
|
+
* - `data` (object | undefined): Present on success
|
|
947
|
+
* - `key` (string): The requested key
|
|
948
|
+
* - `value` (string): The stored value
|
|
949
|
+
* - `error` (string | undefined): Error message (e.g., "Key not found")
|
|
950
|
+
* - `errorDetails` (object | undefined): Detailed error info on failure
|
|
951
|
+
*/
|
|
952
|
+
get: (key: string) => Promise<MemoryGetResponse>;
|
|
953
|
+
/**
|
|
954
|
+
* Delete a key from session memory
|
|
955
|
+
*
|
|
956
|
+
* Remove a key-value pair. Succeeds even if the key doesn't exist.
|
|
957
|
+
*
|
|
958
|
+
* @param key The key to delete
|
|
959
|
+
* @returns Promise with success status and the deleted key
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* ```ts
|
|
963
|
+
* // Clean up temporary data
|
|
964
|
+
* const result = await sdk.memory.delete("tempSwapQuote");
|
|
965
|
+
*
|
|
966
|
+
* if (result.success && result.data) {
|
|
967
|
+
* console.log(`Deleted key: ${result.data.key}`);
|
|
968
|
+
* }
|
|
969
|
+
* ```
|
|
970
|
+
*
|
|
971
|
+
* **Input**: `key: string`
|
|
972
|
+
*
|
|
973
|
+
* **Output**: `MemoryDeleteResponse`
|
|
974
|
+
* - `success` (bool): Whether the operation succeeded
|
|
975
|
+
* - `data` (object | undefined): Present on success
|
|
976
|
+
* - `key` (string): The key that was deleted
|
|
977
|
+
* - `error` (string | undefined): Error message on failure
|
|
978
|
+
* - `errorDetails` (object | undefined): Detailed error info on failure
|
|
979
|
+
*/
|
|
980
|
+
delete: (key: string) => Promise<MemoryDeleteResponse>;
|
|
981
|
+
/**
|
|
982
|
+
* List all keys in session memory
|
|
983
|
+
*
|
|
984
|
+
* Get an array of all keys stored for this agent session. Useful for debugging
|
|
985
|
+
* or iterating through stored data.
|
|
986
|
+
*
|
|
987
|
+
* @returns Promise with array of keys and count
|
|
988
|
+
*
|
|
989
|
+
* @example
|
|
990
|
+
* ```ts
|
|
991
|
+
* // List all stored keys
|
|
992
|
+
* const result = await sdk.memory.list();
|
|
993
|
+
*
|
|
994
|
+
* if (result.success && result.data) {
|
|
995
|
+
* console.log(`Found ${result.data.count} keys:`);
|
|
996
|
+
* result.data.keys.forEach(key => console.log(` - ${key}`));
|
|
997
|
+
* }
|
|
998
|
+
* ```
|
|
999
|
+
*
|
|
1000
|
+
* **Input**: None
|
|
1001
|
+
*
|
|
1002
|
+
* **Output**: `MemoryListResponse`
|
|
1003
|
+
* - `success` (bool): Whether the operation succeeded
|
|
1004
|
+
* - `data` (object | undefined): Present on success
|
|
1005
|
+
* - `keys` (string[]): Array of all stored keys
|
|
1006
|
+
* - `count` (number): Number of keys
|
|
1007
|
+
* - `error` (string | undefined): Error message on failure
|
|
1008
|
+
* - `errorDetails` (object | undefined): Detailed error info on failure
|
|
1009
|
+
*/
|
|
1010
|
+
list: () => Promise<MemoryListResponse>;
|
|
1011
|
+
};
|
|
778
1012
|
/**
|
|
779
1013
|
* π Polymarket: Trade prediction markets seamlessly
|
|
780
1014
|
*
|
|
@@ -942,8 +1176,10 @@ declare class AgentSdk {
|
|
|
942
1176
|
*
|
|
943
1177
|
* if (result.success && result.data) {
|
|
944
1178
|
* result.data.forEach(tx => {
|
|
945
|
-
* if (tx.success) {
|
|
1179
|
+
* if (tx.success && tx.position) {
|
|
946
1180
|
* console.log(`Redeemed ${tx.position.question}: Tx ${tx.transactionHash}`);
|
|
1181
|
+
* } else if (tx.success) {
|
|
1182
|
+
* console.log(`Unwrapped collateral: Tx ${tx.transactionHash}`);
|
|
947
1183
|
* }
|
|
948
1184
|
* });
|
|
949
1185
|
* }
|
|
@@ -964,6 +1200,11 @@ declare class AgentSdk {
|
|
|
964
1200
|
* },
|
|
965
1201
|
* transactionHash: "0xabc123..."
|
|
966
1202
|
* },
|
|
1203
|
+
* {
|
|
1204
|
+
* success: true,
|
|
1205
|
+
* position: null, // null for unwrap collateral transactions
|
|
1206
|
+
* transactionHash: "0xdef456..."
|
|
1207
|
+
* },
|
|
967
1208
|
* // ... more redemptions
|
|
968
1209
|
* ]
|
|
969
1210
|
* }
|
|
@@ -1011,6 +1252,22 @@ declare class AgentSdk {
|
|
|
1011
1252
|
private handlePolymarketPositions;
|
|
1012
1253
|
private handlePolymarketMarketOrder;
|
|
1013
1254
|
private handlePolymarketRedeemPositions;
|
|
1255
|
+
/**
|
|
1256
|
+
* Handle memory set requests
|
|
1257
|
+
*/
|
|
1258
|
+
private handleMemorySet;
|
|
1259
|
+
/**
|
|
1260
|
+
* Handle memory get requests
|
|
1261
|
+
*/
|
|
1262
|
+
private handleMemoryGet;
|
|
1263
|
+
/**
|
|
1264
|
+
* Handle memory delete requests
|
|
1265
|
+
*/
|
|
1266
|
+
private handleMemoryDelete;
|
|
1267
|
+
/**
|
|
1268
|
+
* Handle memory list requests
|
|
1269
|
+
*/
|
|
1270
|
+
private handleMemoryList;
|
|
1014
1271
|
}
|
|
1015
1272
|
|
|
1016
1273
|
/**
|
|
@@ -1069,6 +1326,11 @@ declare class APIClient {
|
|
|
1069
1326
|
* @param data - Optional JSON payload to serialize
|
|
1070
1327
|
*/
|
|
1071
1328
|
post<T>(endpoint: string, data?: any): Promise<T>;
|
|
1329
|
+
/**
|
|
1330
|
+
* HTTP DELETE convenience method.
|
|
1331
|
+
* @param endpoint - API path beginning with `/v1/...`
|
|
1332
|
+
*/
|
|
1333
|
+
delete<T>(endpoint: string): Promise<T>;
|
|
1072
1334
|
}
|
|
1073
1335
|
|
|
1074
1336
|
/**
|
|
@@ -1292,4 +1554,4 @@ declare function isSolanaNetwork(network: Network): network is "solana";
|
|
|
1292
1554
|
*/
|
|
1293
1555
|
declare function getChainIdFromNetwork(network: `ethereum:${number}`): number;
|
|
1294
1556
|
|
|
1295
|
-
export { APIClient, Agent, AgentSdk, type ExecutionFunctionContract, type Network, type PolymarketMarketOrderRequest, type PolymarketMarketOrderResponse, type PolymarketPosition, type PolymarketPositionsResponse, type PolymarketRedeemPositionsRequest, type PolymarketRedeemPositionsResponse, QUOTE_RESULT, type SDKConfig, type SignAndSendRequest, type SignAndSendResponse, type SignMessageRequest, type SignMessageResponse, type StopFunctionContract, type SwidgeExecuteResponse, type SwidgeQuoteRequest, type SwidgeQuoteResponse, type SwidgeQuoteResult, getChainIdFromNetwork, isEthereumNetwork, isSolanaNetwork };
|
|
1557
|
+
export { APIClient, Agent, AgentSdk, type ExecutionFunctionContract, type MemoryDeleteRequest, type MemoryDeleteResponse, type MemoryGetRequest, type MemoryGetResponse, type MemoryListRequest, type MemoryListResponse, type MemorySetRequest, type MemorySetResponse, type Network, type PolymarketMarketOrderRequest, type PolymarketMarketOrderResponse, type PolymarketPosition, type PolymarketPositionsResponse, type PolymarketRedeemPositionsRequest, type PolymarketRedeemPositionsResponse, QUOTE_RESULT, type SDKConfig, type SignAndSendRequest, type SignAndSendResponse, type SignMessageRequest, type SignMessageResponse, type StopFunctionContract, type SwidgeExecuteResponse, type SwidgeQuoteRequest, type SwidgeQuoteResponse, type SwidgeQuoteResult, getChainIdFromNetwork, isEthereumNetwork, isSolanaNetwork };
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var __getOwnPropNames=Object.getOwnPropertyNames,__require=(t=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(t,{get:(t,e)=>("undefined"!=typeof require?require:t)[e]}):t)(function(t){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),__commonJS=(t,e)=>function(){return e||(0,t[__getOwnPropNames(t)[0]])((e={exports:{}}).exports,e),e.exports},require_auth_loader=__commonJS({"src/utils/auth-loader.cjs"(exports,module){function loadAuthFromFileSystem(){try{if("undefined"==typeof process)return;const fs=eval("require")("fs"),path=eval("require")("path"),os=eval("require")("os"),homeDir=os.homedir();let authPath=path.join(homeDir,".config","circuit","auth.json");if(!fs.existsSync(authPath)&&(authPath=path.join(homeDir,".circuit","auth.json"),!fs.existsSync(authPath)))return;const authContent=fs.readFileSync(authPath,"utf-8");return JSON.parse(authContent)}catch(t){return}}module.exports={loadAuthFromFileSystem:loadAuthFromFileSystem}}}),API_BASE_URL_LOCAL="https://agents.circuit.org",APIClient=class{config;baseUrl;isCloudflareWorker(){return"undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare}hasServiceBinding(){let t=!1;return this.isCloudflareWorker()&&(void 0!==globalThis.AGENTS_TO_API_PROXY||void 0!==globalThis.__AGENT_ENV__&&globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)&&(t=!0),this.config.verbose,t}constructor(t){this.config=t,this.baseUrl=t.baseUrl||API_BASE_URL_LOCAL}getAgentSlug(){return"undefined"!=typeof process&&process.env?.CIRCUIT_AGENT_SLUG?process.env.CIRCUIT_AGENT_SLUG:void 0!==globalThis.CIRCUIT_AGENT_SLUG?globalThis.CIRCUIT_AGENT_SLUG:void 0}getAuthHeaders(){const t={};t["X-Session-Id"]=this.config.sessionId.toString();const e=this.getAgentSlug();if(e&&(t["X-Agent-Slug"]=e),!this.hasServiceBinding())try{const e=this.loadAuthConfig();e?.sessionToken&&(t.Authorization=`Bearer ${e.sessionToken}`)}catch(t){}return t}loadAuthConfig(){try{const{loadAuthFromFileSystem:t}=require_auth_loader();return t()}catch(t){this.config.verbose}}logging(t,e){this.config.verbose}sanitizeHeaders(t){const e={},s=new Set(["report-to","server-timing","server"]),r=t&&"object"==typeof t?t:{};for(const[t,a]of Object.entries(r)){if("string"!=typeof a)continue;const r=t.toLowerCase();s.has(r)||(e[t]="authorization"===r?a.startsWith("Bearer ")?`Bearer ${a.slice(7,14)}***`:"***":a)}return e}async makeRequest(t,e={}){const s={...{"Content-Type":"application/json",...this.getAuthHeaders()},...e.headers};let r;if(this.logging("=== REQUEST DETAILS ==="),this.logging("Endpoint:",t),this.logging("Method:",e.method||"GET"),this.logging("Headers:",this.sanitizeHeaders(s)),this.logging("Body:",e.body),this.logging("Session ID:",this.config.sessionId),this.logging("Agent Slug:",this.getAgentSlug()||"not set"),this.logging("Using Service Binding:",this.hasServiceBinding()),this.logging("====================="),this.hasServiceBinding()){let a;if(void 0!==globalThis.AGENTS_TO_API_PROXY)a=globalThis.AGENTS_TO_API_PROXY;else{if(void 0===globalThis.__AGENT_ENV__||!globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)throw new Error("Service binding detected but not accessible");a=globalThis.__AGENT_ENV__.AGENTS_TO_API_PROXY}this.logging("Using service binding AGENTS_TO_API_PROXY"),this.logging("Service binding type:",typeof a);const i={...e,headers:s},o=`https://agents-to-api-proxy.circuit-0bc.workers.dev${t}`;r=await a.fetch(o,i)}else{this.logging("Using HTTP fallback to:",this.baseUrl);const a=`${this.baseUrl}${t}`,i={...e,headers:s};r=await fetch(a,i)}if(this.logging("=== RESPONSE DETAILS ==="),this.logging("Status:",r.status),this.logging("Status Text:",r.statusText),this.logging("Response Headers:",this.sanitizeHeaders(Object.fromEntries(r.headers.entries()))),this.logging("======================"),!r.ok){const t=await r.json().catch(()=>({}));throw this.logging("=== ERROR RESPONSE ==="),this.logging("Error Data:",t),this.logging("===================="),new Error(t.error||t.message||`HTTP ${r.status}: ${r.statusText}`)}const a=await r.json();return this.logging("=== SUCCESS RESPONSE ==="),this.logging("Response Data:",a),this.logging("======================"),a}async get(t){return this.makeRequest(t,{method:"GET"})}async post(t,e){return this.makeRequest(t,{method:"POST",body:e?JSON.stringify(e):void 0})}};function isEthereumNetwork(t){return t.startsWith("ethereum:")}function isSolanaNetwork(t){return"solana"===t}function getChainIdFromNetwork(t){return Number(t.split(":")[1])}var AgentSdk=class{client;config;constructor(t){this.config=t,this.client=new APIClient(t)}logging(t,e){this.config.verbose}async sendLog(t){this.logging("=== ADD MESSAGE ==="),this.logging("Message:",t),this.logging("===================");try{await this._sendLog([t])}catch(t){this.logging("=== SEND LOG ERROR ==="),this.logging("Error:",t),this.logging("======================")}}async signAndSend(t){this.logging("=== SIGN AND SEND ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("====================");try{if(this.config.testing)return{success:!0,internalTransactionId:123,txHash:isEthereumNetwork(t.network)?"0xTEST":"TEST_SOL_TX",transactionUrl:void 0};if(isEthereumNetwork(t.network)){const e=getChainIdFromNetwork(t.network);if("toAddress"in t.request)return await this.handleEvmTransaction({chainId:e,toAddress:t.request.toAddress,data:t.request.data,valueWei:t.request.value,message:t.message})}return isSolanaNetwork(t.network)&&"hexTransaction"in t.request?await this.handleSolanaTransaction({hexTransaction:t.request.hexTransaction,message:t.message}):{success:!1,error:`Unsupported network: ${t.network}`,errorDetails:{message:`Unsupported network: ${t.network}`}}}catch(t){return this.logging("=== SIGN AND SEND ERROR ==="),this.logging("Error:",t),this.logging("==========================="),{success:!1,error:t instanceof Error?t.message:"Unknown error",errorDetails:{message:t instanceof Error?t.message:"Unknown error"}}}}async signMessage(t){this.logging("=== SIGN MESSAGE ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("====================");try{return this.config.testing?{v:27,r:"0xTEST_R",s:"0xTEST_S",formattedSignature:"0xTEST_FORMATTED",type:"evm"}:isEthereumNetwork(t.network)?await this.handleEvmSignMessage(t):{v:0,r:"0x0",s:"0x0",formattedSignature:"0x0",type:"evm"}}catch(t){return this.logging("=== SIGN MESSAGE ERROR ==="),this.logging("Error:",t),this.logging("=========================="),{v:0,r:"0x0",s:"0x0",formattedSignature:"0x0",type:"evm"}}}swidge={quote:async t=>this.handleSwidgeQuote(t),execute:async t=>this.handleSwidgeExecute(t)};polymarket={positions:async()=>this.handlePolymarketPositions(),marketOrder:async t=>this.handlePolymarketMarketOrder(t),redeemPositions:async t=>this.handlePolymarketRedeemPositions(t||{tokenIds:[]})};async handleEvmTransaction(t){try{const e=await this.client.post("/v1/transactions/evm",t),s=await this.client.post(`/v1/transactions/evm/${e.internalTransactionId}/broadcast`);return{success:!0,internalTransactionId:e.internalTransactionId,txHash:s.txHash,transactionUrl:s.transactionUrl}}catch(t){this.logging("=== EVM TRANSACTION ERROR ==="),this.logging("Error:",t),this.logging("=============================");let e,s,r,a="Unknown error";if(t instanceof Error){a=t.message;const i=t.message.match(/HTTP (\d+): (.+)/);i&&(e=Number.parseInt(i[1]),s=i[2]),t.message.includes("Failed to estimate gas")&&(r=t.message)}return{success:!1,error:a,errorDetails:{message:r||a,status:e,statusText:s}}}}async handleSolanaTransaction(t){try{const e=await this.client.post("/v1/transactions/solana",t),s=await this.client.post(`/v1/transactions/solana/${e.internalTransactionId}/broadcast`);return{success:!0,internalTransactionId:e.internalTransactionId,txHash:s.txHash,transactionUrl:s.transactionUrl}}catch(t){this.logging("=== SOLANA TRANSACTION ERROR ==="),this.logging("Error:",t),this.logging("================================");let e,s,r="Unknown error";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleEvmSignMessage(t){try{return await this.client.post("/v1/messages/evm",{messageType:t.request.messageType,data:t.request.data,chainId:t.request.chainId})}catch(t){return this.logging("=== EVM SIGN MESSAGE ERROR ==="),this.logging("Error:",t),this.logging("=============================="),{v:0,r:"0x0",s:"0x0",formattedSignature:"0x0",type:"evm"}}}async _sendLog(t){return this.config.testing?{status:200,message:"Logs added successfully (TESTING)"}:this.client.post("/v1/logs",t)}async _updateJobStatus(t){if(this.logging("UPDATE_JOB_STATUS",t),this.config.testing)return{status:200,message:"Job status updated successfully (TESTING)"};try{return await this.client.post(`/v1/jobs/${t.jobId}/status`,t)}catch(t){return this.logging("=== UPDATE JOB STATUS ERROR ==="),this.logging("Error:",t),this.logging("==============================="),{status:400,message:`Failed to update job status: ${t instanceof Error?t.message:"Unknown error"}`}}}async handleSwidgeQuote(t){this.logging("=== SWIDGE QUOTE ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("===================");try{return this.config.testing?{success:!0,data:{engine:"relay",assetSend:{network:t.from.network,address:t.from.address,token:t.fromToken||null,amount:t.amount,amountFormatted:"1.0",amountUsd:"100.00"},assetReceive:{network:t.to.network,address:t.to.address,token:t.toToken||null,amount:"950000000000000000",amountFormatted:"0.95",amountUsd:"95.00"},priceImpact:{percentage:"0.5",usd:"5.00"},fees:[{name:"gas",amount:"21000000000000000",amountFormatted:"0.021",amountUsd:"2.10"}],steps:[{type:"transaction",description:"Test swap transaction",transactionDetails:{type:"evm",from:"0xtest",to:"0xtest",chainId:1,value:0,data:"0x",gas:21e3,maxFeePerGas:2e10,maxPriorityFeePerGas:1e9},metadata:{requestId:"test-request-id"}}]}}:{success:!0,data:await this.client.post("/v1/swidge/quote",t)}}catch(t){this.logging("=== SWIDGE QUOTE ERROR ==="),this.logging("Error:",t),this.logging("=========================");let e,s,r="Failed to get swidge quote";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleSwidgeExecute(t){this.logging("=== SWIDGE EXECUTE ==="),this.logging("Quote:",t),this.logging("Testing mode:",this.config.testing),this.logging("=====================");try{if(this.config.testing)return{success:!0,data:{status:"success",in:{network:t.assetSend.network,txs:["0xtest_in_tx"]},out:{network:t.assetReceive.network,txs:["0xtest_out_tx"]},lastUpdated:Date.now()}};this.logging("Making execute request to /v1/swidge/execute");const e=await this.client.post("/v1/swidge/execute",t);return this.logging("Execute response received:",JSON.stringify(e,null,2)),{success:!0,data:e}}catch(t){this.logging("=== SWIDGE EXECUTE ERROR ==="),this.logging("Error:",t),this.logging("============================");let e,s,r="Failed to execute swidge swap";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handlePolymarketPositions(){this.logging("=== POLYMARKET POSITIONS ==="),this.logging("Testing mode:",this.config.testing),this.logging("===========================");try{return this.config.testing?{success:!0,data:{totalValue:0,positions:[]}}:{success:!0,data:await this.client.get("/v1/platforms/polymarket/positions")}}catch(t){this.logging("=== POLYMARKET POSITIONS ERROR ==="),this.logging("Error:",t),this.logging("=================================");let e,s,r="Failed to get polymarket positions";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handlePolymarketMarketOrder(t){this.logging("=== POLYMARKET MARKET ORDER ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("==============================");try{return this.config.testing?{success:!0,data:{success:!0,orderInfo:{orderId:"test-order-id",side:"BUY",size:"1.0",priceUsd:"0.50",totalPriceUsd:"0.50",txHashes:["0xtest"]}}}:{success:!0,data:await this.client.post("/v1/platforms/polymarket/market-order",t)}}catch(t){this.logging("=== POLYMARKET MARKET ORDER ERROR ==="),this.logging("Error:",t),this.logging("====================================");let e,s,r="Failed to execute polymarket market order";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handlePolymarketRedeemPositions(t){this.logging("=== POLYMARKET REDEEM POSITIONS ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("==================================");try{return this.config.testing?{success:!0,data:[]}:{success:!0,data:await this.client.post("/v1/platforms/polymarket/redeem-positions",t)}}catch(t){this.logging("=== POLYMARKET REDEEM POSITIONS ERROR ==="),this.logging("Error:",t),this.logging("========================================");let e,s,r="Failed to redeem polymarket positions";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}};import{zValidator}from"@hono/zod-validator";import{Hono}from"hono";import{cors}from"hono/cors";import{z}from"zod";var CurrentPositionSchema=z.object({network:z.string(),assetAddress:z.string(),tokenId:z.string().nullable(),avgUnitCost:z.string(),currentQty:z.string()}),AgentRequestSchema=z.object({sessionId:z.number(),sessionWalletAddress:z.string(),jobId:z.string().optional(),currentPositions:z.array(CurrentPositionSchema).optional(),otherParameters:z.object().optional()}),AgentResponseSchema=z.object({success:z.boolean(),error:z.string().optional(),message:z.string().optional()}),HealthResponseSchema=z.object({status:z.string()}),Agent=class{app;executionFunction;stopFunction;healthCheckFunction;constructor(t){this.app=new Hono,this.executionFunction=t.executionFunction,this.stopFunction=t.stopFunction,this.healthCheckFunction=t.healthCheckFunction||(async()=>({status:"healthy"})),this.app.use("*",cors()),this.setupRoutes()}defaultStopFunction=async t=>({success:!0,message:`Agent stopped for session ${t.sessionId}`});async executeWithJobTracking(t,e){try{const s=await e(t);if(t.jobId&&s.success)try{await this.updateJobStatus(t.sessionId,t.jobId,"success")}catch(t){}else if(t.jobId&&!s.success)try{const e=s.error||s.message||"Function returned failure";await this.updateJobStatus(t.sessionId,t.jobId,"failed",e)}catch(t){}return s}catch(e){if(t.jobId)try{const s=e instanceof Error?e.message:"Unknown error";await this.updateJobStatus(t.sessionId,t.jobId,"failed",s)}catch(t){}return{success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Function execution failed"}}}async updateJobStatus(t,e,s,r){try{const a=new AgentSdk({sessionId:t}),i={jobId:e,status:s,...r&&{errorMessage:r}};await a._updateJobStatus(i)}catch(t){}}setupRoutes(){this.app.post("/execute",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=await this.executeWithJobTracking(e,this.executionFunction);return t.json(s)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Execution failed"},500)}}),this.app.post("/stop",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=this.stopFunction||this.defaultStopFunction,r=await this.executeWithJobTracking(e,s);return t.json(r)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Stop operation failed"},500)}}),this.app.get("/health",async t=>{try{const e=await(this.healthCheckFunction?.());return t.json(e)}catch(e){return t.json({status:"unhealthy",error:e instanceof Error?e.message:"Unknown error",timestamp:(new Date).toISOString()},500)}})}getPortFromPackageJson(){try{const t=__require("fs"),e=__require("path").join(process.cwd(),"package.json");if(t.existsSync(e)){const s=JSON.parse(t.readFileSync(e,"utf-8"));if(s.circuit?.port)return Number.parseInt(s.circuit.port,10)}}catch(t){}return null}run(port){const isCloudflareWorker="undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare;if(isCloudflareWorker)return this.getWorkerExport();const bunEnv=globalThis.Bun?.env,envPort=process.env.AGENT_PORT||bunEnv?.AGENT_PORT,packageJsonPort=this.getPortFromPackageJson();let finalPort=port;!finalPort&&envPort&&(finalPort=Number.parseInt(envPort,10)),!finalPort&&packageJsonPort&&(finalPort=packageJsonPort),finalPort||(finalPort=3e3);try{const req=eval("require"),{serve:serve}=req("@hono/node-server");serve({fetch:this.app.fetch,port:finalPort})}catch(t){process.exit(1)}}getWorkerExport(){return{fetch:async(t,e,s)=>(e&&"undefined"!=typeof globalThis&&(globalThis.__AGENT_ENV__=e),this.app.fetch(t,e,s))}}};function createAgentHandler(t,e,s){return new Agent({executionFunction:t,stopFunction:e,healthCheckFunction:s})}import{z as z2}from"zod";var zEthereumNetwork=z2.templateLiteral(["ethereum:",z2.coerce.number().int().nonnegative()]),SwidgeNetworkSchema=z2.union([z2.literal("solana"),zEthereumNetwork]),SwidgeWalletSchema=z2.object({address:z2.string(),network:SwidgeNetworkSchema}),SwidgeQuoteRequestSchema=z2.object({from:SwidgeWalletSchema,to:SwidgeWalletSchema,fromToken:z2.string().optional(),toToken:z2.string().optional(),amount:z2.string(),priceImpact:z2.string().optional(),slippage:z2.string().optional()}),SwidgeQuoteAssetSchema=z2.object({network:SwidgeNetworkSchema,address:z2.string(),token:z2.string().nullable(),name:z2.string().optional(),symbol:z2.string().optional(),decimals:z2.number().optional(),amount:z2.string().optional(),minimumAmount:z2.string().optional(),amountFormatted:z2.string().optional(),amountUsd:z2.string().optional()}),SwidgePriceImpactSchema=z2.object({usd:z2.string().optional(),percentage:z2.string().optional()}),SwidgeFeeSchema=z2.object({name:z2.string(),amount:z2.string().optional(),amountFormatted:z2.string().optional(),amountUsd:z2.string().optional()}),SwidgeSolanaInstructionSchema=z2.object({programId:z2.string(),keys:z2.array(z2.object({pubkey:z2.string(),isSigner:z2.boolean(),isWritable:z2.boolean()})),data:z2.union([z2.string(),z2.instanceof(Buffer)])}),SwidgeEvmTransactionDetailsSchema=z2.object({type:z2.literal("evm"),from:z2.string().regex(/^0x[a-fA-F0-9]{40}$/),to:z2.string().regex(/^0x[a-fA-F0-9]{40}$/),chainId:z2.number(),value:z2.number(),data:z2.string().regex(/^0x[a-fA-F0-9]*$/),gas:z2.number().optional(),maxFeePerGas:z2.number().optional(),maxPriorityFeePerGas:z2.number().optional()}),SwidgeSolanaTransactionDetailsSchema=z2.object({type:z2.literal("solana"),instructions:z2.array(SwidgeSolanaInstructionSchema),addressLookupTableAddresses:z2.array(z2.string())}),zTransactionStep=z2.object({type:z2.literal("transaction"),description:z2.string(),transactionDetails:z2.union([SwidgeEvmTransactionDetailsSchema,SwidgeSolanaTransactionDetailsSchema]),metadata:z2.record(z2.string(),z2.string())}),zUnsignedSignatureStep=z2.object({type:z2.literal("signature"),description:z2.string(),signatureData:z2.string(),metadata:z2.record(z2.string(),z2.string())}),SwidgeUnsignedStepSchema=z2.discriminatedUnion("type",[zTransactionStep,zUnsignedSignatureStep]),SwidgeQuoteDataSchema=z2.object({engine:z2.literal("relay"),assetSend:SwidgeQuoteAssetSchema,assetReceive:SwidgeQuoteAssetSchema,priceImpact:SwidgePriceImpactSchema,fees:z2.array(SwidgeFeeSchema),steps:z2.array(SwidgeUnsignedStepSchema)}),SwidgeStatusInfoSchema=z2.object({network:z2.string(),txs:z2.array(z2.string())}),SwidgeExecuteResponseSchema=z2.object({status:z2.union([z2.literal("success"),z2.literal("failure"),z2.literal("refund"),z2.literal("delayed")]),in:SwidgeStatusInfoSchema,out:SwidgeStatusInfoSchema,lastUpdated:z2.number()}),QUOTE_RESULT={FOUND:"QUOTE_FOUND",NO_QUOTE_PROVIDED:"No quote provided",WALLET_NOT_FOUND:"Wallet not found",WALLET_MISMATCH:"From wallet does not match session wallet",PRICE_IMPACT_TOO_HIGH:"Failed to get quote. Error: Price impact is too high",NO_ROUTES_FOUND:"Failed to get quote. Error: no routes found",AMOUNT_TOO_SMALL:"Failed to get quote. APIError: Swap output amount is too small to cover fees required to execute swap"},SwidgeSDKResponseSchema=t=>z2.object({success:z2.boolean(),data:t.optional(),error:z2.string().optional(),errorDetails:z2.object({message:z2.string(),status:z2.number().optional(),statusText:z2.string().optional()}).optional()}),SwidgeQuoteResponseWrapperSchema=SwidgeSDKResponseSchema(SwidgeQuoteDataSchema),SwidgeExecuteResponseWrapperSchema=SwidgeSDKResponseSchema(SwidgeExecuteResponseSchema);export{APIClient,Agent,AgentSdk,QUOTE_RESULT,getChainIdFromNetwork,isEthereumNetwork,isSolanaNetwork};
|
|
1
|
+
var __getOwnPropNames=Object.getOwnPropertyNames,__require=(t=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(t,{get:(t,e)=>("undefined"!=typeof require?require:t)[e]}):t)(function(t){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),__commonJS=(t,e)=>function(){return e||(0,t[__getOwnPropNames(t)[0]])((e={exports:{}}).exports,e),e.exports},require_auth_loader=__commonJS({"src/utils/auth-loader.cjs"(exports,module){function loadAuthFromFileSystem(){try{if("undefined"==typeof process)return;const fs=eval("require")("fs"),path=eval("require")("path"),os=eval("require")("os"),homeDir=os.homedir();let authPath=path.join(homeDir,".config","circuit","auth.json");if(!fs.existsSync(authPath)&&(authPath=path.join(homeDir,".circuit","auth.json"),!fs.existsSync(authPath)))return;const authContent=fs.readFileSync(authPath,"utf-8");return JSON.parse(authContent)}catch(t){return}}module.exports={loadAuthFromFileSystem:loadAuthFromFileSystem}}}),API_BASE_URL_LOCAL="https://agents.circuit.org",APIClient=class{config;baseUrl;isCloudflareWorker(){return"undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare}hasServiceBinding(){let t=!1;return this.isCloudflareWorker()&&(void 0!==globalThis.AGENTS_TO_API_PROXY||void 0!==globalThis.__AGENT_ENV__&&globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)&&(t=!0),this.config.verbose,t}constructor(t){this.config=t,this.baseUrl=t.baseUrl||API_BASE_URL_LOCAL}getAgentSlug(){return"undefined"!=typeof process&&process.env?.CIRCUIT_AGENT_SLUG?process.env.CIRCUIT_AGENT_SLUG:void 0!==globalThis.CIRCUIT_AGENT_SLUG?globalThis.CIRCUIT_AGENT_SLUG:void 0}getAuthHeaders(){const t={};t["X-Session-Id"]=this.config.sessionId.toString();const e=this.getAgentSlug();if(e&&(t["X-Agent-Slug"]=e),!this.hasServiceBinding())try{const e=this.loadAuthConfig();e?.sessionToken&&(t.Authorization=`Bearer ${e.sessionToken}`)}catch(t){}return t}loadAuthConfig(){try{const{loadAuthFromFileSystem:t}=require_auth_loader();return t()}catch(t){this.config.verbose}}logging(t,e){this.config.verbose}sanitizeHeaders(t){const e={},s=new Set(["report-to","server-timing","server"]),r=t&&"object"==typeof t?t:{};for(const[t,a]of Object.entries(r)){if("string"!=typeof a)continue;const r=t.toLowerCase();s.has(r)||(e[t]="authorization"===r?a.startsWith("Bearer ")?`Bearer ${a.slice(7,14)}***`:"***":a)}return e}async makeRequest(t,e={}){const s={...{"Content-Type":"application/json",...this.getAuthHeaders()},...e.headers};let r;if(this.logging("=== REQUEST DETAILS ==="),this.logging("Endpoint:",t),this.logging("Method:",e.method||"GET"),this.logging("Headers:",this.sanitizeHeaders(s)),this.logging("Body:",e.body),this.logging("Session ID:",this.config.sessionId),this.logging("Agent Slug:",this.getAgentSlug()||"not set"),this.logging("Using Service Binding:",this.hasServiceBinding()),this.logging("====================="),this.hasServiceBinding()){let a;if(void 0!==globalThis.AGENTS_TO_API_PROXY)a=globalThis.AGENTS_TO_API_PROXY;else{if(void 0===globalThis.__AGENT_ENV__||!globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)throw new Error("Service binding detected but not accessible");a=globalThis.__AGENT_ENV__.AGENTS_TO_API_PROXY}this.logging("Using service binding AGENTS_TO_API_PROXY"),this.logging("Service binding type:",typeof a);const i={...e,headers:s},o=`https://agents-to-api-proxy.circuit-0bc.workers.dev${t}`;r=await a.fetch(o,i)}else{this.logging("Using HTTP fallback to:",this.baseUrl);const a=`${this.baseUrl}${t}`,i={...e,headers:s};r=await fetch(a,i)}if(this.logging("=== RESPONSE DETAILS ==="),this.logging("Status:",r.status),this.logging("Status Text:",r.statusText),this.logging("Response Headers:",this.sanitizeHeaders(Object.fromEntries(r.headers.entries()))),this.logging("======================"),!r.ok){const t=await r.json().catch(()=>({}));throw this.logging("=== ERROR RESPONSE ==="),this.logging("Error Data:",t),this.logging("===================="),new Error(t.error||t.message||`HTTP ${r.status}: ${r.statusText}`)}const a=await r.json();return this.logging("=== SUCCESS RESPONSE ==="),this.logging("Response Data:",a),this.logging("======================"),a}async get(t){return this.makeRequest(t,{method:"GET"})}async post(t,e){return this.makeRequest(t,{method:"POST",body:e?JSON.stringify(e):void 0})}async delete(t){return this.makeRequest(t,{method:"DELETE"})}};function isEthereumNetwork(t){return t.startsWith("ethereum:")}function isSolanaNetwork(t){return"solana"===t}function getChainIdFromNetwork(t){return Number(t.split(":")[1])}var AgentSdk=class{client;config;constructor(t){this.config=t,this.client=new APIClient(t)}logging(t,e){this.config.verbose}async sendLog(t){this.logging("=== ADD MESSAGE ==="),this.logging("Message:",t),this.logging("===================");try{await this._sendLog([t])}catch(t){this.logging("=== SEND LOG ERROR ==="),this.logging("Error:",t),this.logging("======================")}}async signAndSend(t){this.logging("=== SIGN AND SEND ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("====================");try{if(this.config.testing)return{success:!0,internalTransactionId:123,txHash:isEthereumNetwork(t.network)?"0xTEST":"TEST_SOL_TX",transactionUrl:void 0};if(isEthereumNetwork(t.network)){const e=getChainIdFromNetwork(t.network);if("toAddress"in t.request)return await this.handleEvmTransaction({chainId:e,toAddress:t.request.toAddress,data:t.request.data,valueWei:t.request.value,message:t.message})}return isSolanaNetwork(t.network)&&"hexTransaction"in t.request?await this.handleSolanaTransaction({hexTransaction:t.request.hexTransaction,message:t.message}):{success:!1,error:`Unsupported network: ${t.network}`,errorDetails:{message:`Unsupported network: ${t.network}`}}}catch(t){return this.logging("=== SIGN AND SEND ERROR ==="),this.logging("Error:",t),this.logging("==========================="),{success:!1,error:t instanceof Error?t.message:"Unknown error",errorDetails:{message:t instanceof Error?t.message:"Unknown error"}}}}async signMessage(t){this.logging("=== SIGN MESSAGE ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("====================");try{return this.config.testing?{v:27,r:"0xTEST_R",s:"0xTEST_S",formattedSignature:"0xTEST_FORMATTED",type:"evm"}:isEthereumNetwork(t.network)?await this.handleEvmSignMessage(t):{v:0,r:"0x0",s:"0x0",formattedSignature:"0x0",type:"evm"}}catch(t){return this.logging("=== SIGN MESSAGE ERROR ==="),this.logging("Error:",t),this.logging("=========================="),{v:0,r:"0x0",s:"0x0",formattedSignature:"0x0",type:"evm"}}}swidge={quote:async t=>this.handleSwidgeQuote(t),execute:async t=>this.handleSwidgeExecute(t)};memory={set:async(t,e)=>this.handleMemorySet(t,e),get:async t=>this.handleMemoryGet(t),delete:async t=>this.handleMemoryDelete(t),list:async()=>this.handleMemoryList()};polymarket={positions:async()=>this.handlePolymarketPositions(),marketOrder:async t=>this.handlePolymarketMarketOrder(t),redeemPositions:async t=>this.handlePolymarketRedeemPositions(t||{tokenIds:[]})};async handleEvmTransaction(t){try{const e=await this.client.post("/v1/transactions/evm",t),s=await this.client.post(`/v1/transactions/evm/${e.internalTransactionId}/broadcast`);return{success:!0,internalTransactionId:e.internalTransactionId,txHash:s.txHash,transactionUrl:s.transactionUrl}}catch(t){this.logging("=== EVM TRANSACTION ERROR ==="),this.logging("Error:",t),this.logging("=============================");let e,s,r,a="Unknown error";if(t instanceof Error){a=t.message;const i=t.message.match(/HTTP (\d+): (.+)/);i&&(e=Number.parseInt(i[1]),s=i[2]),t.message.includes("Failed to estimate gas")&&(r=t.message)}return{success:!1,error:a,errorDetails:{message:r||a,status:e,statusText:s}}}}async handleSolanaTransaction(t){try{const e=await this.client.post("/v1/transactions/solana",t),s=await this.client.post(`/v1/transactions/solana/${e.internalTransactionId}/broadcast`);return{success:!0,internalTransactionId:e.internalTransactionId,txHash:s.txHash,transactionUrl:s.transactionUrl}}catch(t){this.logging("=== SOLANA TRANSACTION ERROR ==="),this.logging("Error:",t),this.logging("================================");let e,s,r="Unknown error";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleEvmSignMessage(t){try{return await this.client.post("/v1/messages/evm",{messageType:t.request.messageType,data:t.request.data,chainId:t.request.chainId})}catch(t){return this.logging("=== EVM SIGN MESSAGE ERROR ==="),this.logging("Error:",t),this.logging("=============================="),{v:0,r:"0x0",s:"0x0",formattedSignature:"0x0",type:"evm"}}}async _sendLog(t){return this.config.testing?{status:200,message:"Logs added successfully (TESTING)"}:this.client.post("/v1/logs",t)}async _updateJobStatus(t){if(this.logging("UPDATE_JOB_STATUS",t),this.config.testing)return{status:200,message:"Job status updated successfully (TESTING)"};try{return await this.client.post(`/v1/jobs/${t.jobId}/status`,t)}catch(t){return this.logging("=== UPDATE JOB STATUS ERROR ==="),this.logging("Error:",t),this.logging("==============================="),{status:400,message:`Failed to update job status: ${t instanceof Error?t.message:"Unknown error"}`}}}async handleSwidgeQuote(t){this.logging("=== SWIDGE QUOTE ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("===================");try{return this.config.testing?{success:!0,data:{engine:"relay",assetSend:{network:t.from.network,address:t.from.address,token:t.fromToken||null,amount:t.amount,amountFormatted:"1.0",amountUsd:"100.00"},assetReceive:{network:t.to.network,address:t.to.address,token:t.toToken||null,amount:"950000000000000000",amountFormatted:"0.95",amountUsd:"95.00"},priceImpact:{percentage:"0.5",usd:"5.00"},fees:[{name:"gas",amount:"21000000000000000",amountFormatted:"0.021",amountUsd:"2.10"}],steps:[{type:"transaction",description:"Test swap transaction",transactionDetails:{type:"evm",from:"0xtest",to:"0xtest",chainId:1,value:0,data:"0x",gas:21e3,maxFeePerGas:2e10,maxPriorityFeePerGas:1e9},metadata:{requestId:"test-request-id"}}]}}:{success:!0,data:await this.client.post("/v1/swidge/quote",t)}}catch(t){this.logging("=== SWIDGE QUOTE ERROR ==="),this.logging("Error:",t),this.logging("=========================");let e,s,r="Failed to get swidge quote";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleSwidgeExecute(t){this.logging("=== SWIDGE EXECUTE ==="),this.logging("Quote:",t),this.logging("Testing mode:",this.config.testing),this.logging("=====================");try{if(this.config.testing)return{success:!0,data:{status:"success",in:{network:t.assetSend.network,txs:["0xtest_in_tx"]},out:{network:t.assetReceive.network,txs:["0xtest_out_tx"]},lastUpdated:Date.now()}};this.logging("Making execute request to /v1/swidge/execute");const e=await this.client.post("/v1/swidge/execute",t);return this.logging("Execute response received:",JSON.stringify(e,null,2)),{success:!0,data:e}}catch(t){this.logging("=== SWIDGE EXECUTE ERROR ==="),this.logging("Error:",t),this.logging("============================");let e,s,r="Failed to execute swidge swap";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handlePolymarketPositions(){this.logging("=== POLYMARKET POSITIONS ==="),this.logging("Testing mode:",this.config.testing),this.logging("===========================");try{return this.config.testing?{success:!0,data:{totalValue:0,positions:[]}}:{success:!0,data:await this.client.get("/v1/platforms/polymarket/positions")}}catch(t){this.logging("=== POLYMARKET POSITIONS ERROR ==="),this.logging("Error:",t),this.logging("=================================");let e,s,r="Failed to get polymarket positions";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handlePolymarketMarketOrder(t){this.logging("=== POLYMARKET MARKET ORDER ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("==============================");try{return this.config.testing?{success:!0,data:{success:!0,orderInfo:{orderId:"test-order-id",side:"BUY",size:"1.0",priceUsd:"0.50",totalPriceUsd:"0.50",txHashes:["0xtest"]}}}:{success:!0,data:await this.client.post("/v1/platforms/polymarket/market-order",t)}}catch(t){this.logging("=== POLYMARKET MARKET ORDER ERROR ==="),this.logging("Error:",t),this.logging("====================================");let e,s,r="Failed to execute polymarket market order";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handlePolymarketRedeemPositions(t){this.logging("=== POLYMARKET REDEEM POSITIONS ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("==================================");try{return this.config.testing?{success:!0,data:[]}:{success:!0,data:await this.client.post("/v1/platforms/polymarket/redeem-positions",t)}}catch(t){this.logging("=== POLYMARKET REDEEM POSITIONS ERROR ==="),this.logging("Error:",t),this.logging("========================================");let e,s,r="Failed to redeem polymarket positions";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleMemorySet(t,e){this.logging("=== MEMORY SET ==="),this.logging("Key:",t),this.logging("Testing mode:",this.config.testing),this.logging("==================");try{return this.config.testing?{success:!0,data:{key:t}}:{success:!0,data:await this.client.post(`/v1/memory/${t}`,{value:e})}}catch(t){this.logging("=== MEMORY SET ERROR ==="),this.logging("Error:",t),this.logging("========================");let e,s,r="Failed to set memory";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleMemoryGet(t){this.logging("=== MEMORY GET ==="),this.logging("Key:",t),this.logging("Testing mode:",this.config.testing),this.logging("==================");try{return this.config.testing?{success:!0,data:{key:t,value:"test-value"}}:{success:!0,data:await this.client.get(`/v1/memory/${t}`)}}catch(t){this.logging("=== MEMORY GET ERROR ==="),this.logging("Error:",t),this.logging("========================");let e,s,r="Failed to get memory";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleMemoryDelete(t){this.logging("=== MEMORY DELETE ==="),this.logging("Key:",t),this.logging("Testing mode:",this.config.testing),this.logging("=====================");try{return this.config.testing?{success:!0,data:{key:t}}:{success:!0,data:await this.client.delete(`/v1/memory/${t}`)}}catch(t){this.logging("=== MEMORY DELETE ERROR ==="),this.logging("Error:",t),this.logging("===========================");let e,s,r="Failed to delete memory";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}async handleMemoryList(){this.logging("=== MEMORY LIST ==="),this.logging("Testing mode:",this.config.testing),this.logging("===================");try{return this.config.testing?{success:!0,data:{keys:[],count:0}}:{success:!0,data:await this.client.get("/v1/memory/list")}}catch(t){this.logging("=== MEMORY LIST ERROR ==="),this.logging("Error:",t),this.logging("=========================");let e,s,r="Failed to list memory keys";if(t instanceof Error){r=t.message;const a=t.message.match(/HTTP (\d+): (.+)/);a&&(e=Number.parseInt(a[1]),s=a[2])}return{success:!1,error:r,errorDetails:{message:r,status:e,statusText:s}}}}};import{zValidator}from"@hono/zod-validator";import{Hono}from"hono";import{cors}from"hono/cors";import{z}from"zod";var CurrentPositionSchema=z.object({network:z.string(),assetAddress:z.string(),tokenId:z.string().nullable(),avgUnitCost:z.string(),currentQty:z.string()}),AgentRequestSchema=z.object({sessionId:z.number(),sessionWalletAddress:z.string(),jobId:z.string().optional(),currentPositions:z.array(CurrentPositionSchema).optional(),otherParameters:z.object().optional()}),AgentResponseSchema=z.object({success:z.boolean(),error:z.string().optional(),message:z.string().optional()}),HealthResponseSchema=z.object({status:z.string()}),Agent=class{app;executionFunction;stopFunction;healthCheckFunction;constructor(t){this.app=new Hono,this.executionFunction=t.executionFunction,this.stopFunction=t.stopFunction,this.healthCheckFunction=t.healthCheckFunction||(async()=>({status:"healthy"})),this.app.use("*",cors()),this.setupRoutes()}defaultStopFunction=async t=>({success:!0,message:`Agent stopped for session ${t.sessionId}`});async executeWithJobTracking(t,e){try{const s=await e(t);if(t.jobId&&s.success)try{await this.updateJobStatus(t.sessionId,t.jobId,"success")}catch(t){}else if(t.jobId&&!s.success)try{const e=s.error||s.message||"Function returned failure";await this.updateJobStatus(t.sessionId,t.jobId,"failed",e)}catch(t){}return s}catch(e){if(t.jobId)try{const s=e instanceof Error?e.message:"Unknown error";await this.updateJobStatus(t.sessionId,t.jobId,"failed",s)}catch(t){}return{success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Function execution failed"}}}async updateJobStatus(t,e,s,r){try{const a=new AgentSdk({sessionId:t}),i={jobId:e,status:s,...r&&{errorMessage:r}};await a._updateJobStatus(i)}catch(t){}}setupRoutes(){this.app.post("/execute",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=await this.executeWithJobTracking(e,this.executionFunction);return t.json(s)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Execution failed"},500)}}),this.app.post("/stop",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=this.stopFunction||this.defaultStopFunction,r=await this.executeWithJobTracking(e,s);return t.json(r)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Stop operation failed"},500)}}),this.app.get("/health",async t=>{try{const e=await(this.healthCheckFunction?.());return t.json(e)}catch(e){return t.json({status:"unhealthy",error:e instanceof Error?e.message:"Unknown error",timestamp:(new Date).toISOString()},500)}})}getPortFromPackageJson(){try{const t=__require("fs"),e=__require("path").join(process.cwd(),"package.json");if(t.existsSync(e)){const s=JSON.parse(t.readFileSync(e,"utf-8"));if(s.circuit?.port)return Number.parseInt(s.circuit.port,10)}}catch(t){}return null}run(port){const isCloudflareWorker="undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare;if(isCloudflareWorker)return this.getWorkerExport();const bunEnv=globalThis.Bun?.env,envPort=process.env.AGENT_PORT||bunEnv?.AGENT_PORT,packageJsonPort=this.getPortFromPackageJson();let finalPort=port;!finalPort&&envPort&&(finalPort=Number.parseInt(envPort,10)),!finalPort&&packageJsonPort&&(finalPort=packageJsonPort),finalPort||(finalPort=3e3);try{const req=eval("require"),{serve:serve}=req("@hono/node-server");serve({fetch:this.app.fetch,port:finalPort})}catch(t){process.exit(1)}}getWorkerExport(){return{fetch:async(t,e,s)=>(e&&"undefined"!=typeof globalThis&&(globalThis.__AGENT_ENV__=e),this.app.fetch(t,e,s))}}};function createAgentHandler(t,e,s){return new Agent({executionFunction:t,stopFunction:e,healthCheckFunction:s})}import{z as z2}from"zod";var zEthereumNetwork=z2.templateLiteral(["ethereum:",z2.coerce.number().int().nonnegative()]),SwidgeNetworkSchema=z2.union([z2.literal("solana"),zEthereumNetwork]),SwidgeWalletSchema=z2.object({address:z2.string(),network:SwidgeNetworkSchema}),SwidgeQuoteRequestSchema=z2.object({from:SwidgeWalletSchema,to:SwidgeWalletSchema,fromToken:z2.string().optional(),toToken:z2.string().optional(),amount:z2.string(),priceImpact:z2.string().optional(),slippage:z2.string().optional()}),SwidgeQuoteAssetSchema=z2.object({network:SwidgeNetworkSchema,address:z2.string(),token:z2.string().nullable(),name:z2.string().optional(),symbol:z2.string().optional(),decimals:z2.number().optional(),amount:z2.string().optional(),minimumAmount:z2.string().optional(),amountFormatted:z2.string().optional(),amountUsd:z2.string().optional()}),SwidgePriceImpactSchema=z2.object({usd:z2.string().optional(),percentage:z2.string().optional()}),SwidgeFeeSchema=z2.object({name:z2.string(),amount:z2.string().optional(),amountFormatted:z2.string().optional(),amountUsd:z2.string().optional()}),SwidgeSolanaInstructionSchema=z2.object({programId:z2.string(),keys:z2.array(z2.object({pubkey:z2.string(),isSigner:z2.boolean(),isWritable:z2.boolean()})),data:z2.union([z2.string(),z2.instanceof(Buffer)])}),SwidgeEvmTransactionDetailsSchema=z2.object({type:z2.literal("evm"),from:z2.string().regex(/^0x[a-fA-F0-9]{40}$/),to:z2.string().regex(/^0x[a-fA-F0-9]{40}$/),chainId:z2.number(),value:z2.number(),data:z2.string().regex(/^0x[a-fA-F0-9]*$/),gas:z2.number().optional(),maxFeePerGas:z2.number().optional(),maxPriorityFeePerGas:z2.number().optional()}),SwidgeSolanaTransactionDetailsSchema=z2.object({type:z2.literal("solana"),instructions:z2.array(SwidgeSolanaInstructionSchema),addressLookupTableAddresses:z2.array(z2.string())}),zTransactionStep=z2.object({type:z2.literal("transaction"),description:z2.string(),transactionDetails:z2.union([SwidgeEvmTransactionDetailsSchema,SwidgeSolanaTransactionDetailsSchema]),metadata:z2.record(z2.string(),z2.string())}),zUnsignedSignatureStep=z2.object({type:z2.literal("signature"),description:z2.string(),signatureData:z2.string(),metadata:z2.record(z2.string(),z2.string())}),SwidgeUnsignedStepSchema=z2.discriminatedUnion("type",[zTransactionStep,zUnsignedSignatureStep]),SwidgeQuoteDataSchema=z2.object({engine:z2.literal("relay"),assetSend:SwidgeQuoteAssetSchema,assetReceive:SwidgeQuoteAssetSchema,priceImpact:SwidgePriceImpactSchema,fees:z2.array(SwidgeFeeSchema),steps:z2.array(SwidgeUnsignedStepSchema)}),SwidgeStatusInfoSchema=z2.object({network:z2.string(),txs:z2.array(z2.string())}),SwidgeExecuteResponseSchema=z2.object({status:z2.union([z2.literal("success"),z2.literal("failure"),z2.literal("refund"),z2.literal("delayed")]),in:SwidgeStatusInfoSchema,out:SwidgeStatusInfoSchema,lastUpdated:z2.number()}),QUOTE_RESULT={FOUND:"QUOTE_FOUND",NO_QUOTE_PROVIDED:"No quote provided",WALLET_NOT_FOUND:"Wallet not found",WALLET_MISMATCH:"From wallet does not match session wallet",PRICE_IMPACT_TOO_HIGH:"Failed to get quote. Error: Price impact is too high",NO_ROUTES_FOUND:"Failed to get quote. Error: no routes found",AMOUNT_TOO_SMALL:"Failed to get quote. APIError: Swap output amount is too small to cover fees required to execute swap"},SwidgeSDKResponseSchema=t=>z2.object({success:z2.boolean(),data:t.optional(),error:z2.string().optional(),errorDetails:z2.object({message:z2.string(),status:z2.number().optional(),statusText:z2.string().optional()}).optional()}),SwidgeQuoteResponseWrapperSchema=SwidgeSDKResponseSchema(SwidgeQuoteDataSchema),SwidgeExecuteResponseWrapperSchema=SwidgeSDKResponseSchema(SwidgeExecuteResponseSchema);export{APIClient,Agent,AgentSdk,QUOTE_RESULT,getChainIdFromNetwork,isEthereumNetwork,isSolanaNetwork};
|