@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.
Files changed (4) hide show
  1. package/README.md +158 -244
  2. package/index.d.ts +266 -4
  3. package/index.js +1 -1
  4. 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 a simple API surface with just **2 core methods** plus **platform integrations** with full type safety.
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
- - **🎯 Simple API**: 2 core methods (`sendLog()`, `signAndSend()`) + platform integrations
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
- The SDK includes built-in Swidge integration for seamless cross-chain token swaps and bridges.
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, easy-to-use API. Whether you're doing a simple token swap on Ethereum or bridging assets across chains, the same quote-and-execute pattern works for everything.
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
- ### 3. Cross-Chain Swaps & Bridges
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
- ### Swidge API Reference
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
- **Status Meanings:**
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
- ### 4. Polymarket Trading
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
- console.log(`βœ… Redeemed: ${result.position.question}`);
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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circuitorg/agent-sdk",
3
- "version": "1.1.7",
3
+ "version": "1.1.8",
4
4
  "description": "typescript sdk for the Agent Toolset Service",
5
5
  "type": "module",
6
6
  "main": "index.js",