@circuitorg/agent-sdk 1.1.3 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +252 -2
- package/index.d.ts +373 -8
- package/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
> **Clean, type-safe TypeScript SDK for building cross-chain agents on the circuit platform**
|
|
4
4
|
|
|
5
|
-
A TypeScript SDK for building automated agents to deploy on Circuit. Features a simple API surface with just **
|
|
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.
|
|
6
6
|
|
|
7
7
|
> **💡 Best used with [Circuit Agents CLI](https://github.com/circuitorg/agents-cli)** - Deploy, manage, and test your agents with ease
|
|
8
8
|
|
|
9
9
|
## ✨ Features
|
|
10
10
|
|
|
11
|
-
- **🎯 Simple API**:
|
|
11
|
+
- **🎯 Simple API**: 2 core methods (`sendLog()`, `signAndSend()`) + platform integrations
|
|
12
12
|
- **🔒 Type Safety**: Network parameter determines valid request shapes automatically
|
|
13
13
|
- **🚀 Cross-Chain**: Unified interface for EVM and Solana networks
|
|
14
14
|
- **🌉 Cross-Chain Swaps**: Built-in Swidge integration for seamless token swaps and bridges
|
|
15
|
+
- **📈 Polymarket Integration**: Trade prediction markets with `sdk.polymarket.*` methods
|
|
15
16
|
|
|
16
17
|
## 🚀 Quick Start
|
|
17
18
|
### Install the SDK
|
|
@@ -327,6 +328,255 @@ Pass the entire `quote.data` object returned from `quote()` - the SDK handles al
|
|
|
327
328
|
- `"delayed"` - Transaction is taking longer than expected but still processing
|
|
328
329
|
|
|
329
330
|
|
|
331
|
+
## 📈 Polymarket Prediction Markets
|
|
332
|
+
|
|
333
|
+
The SDK includes built-in Polymarket integration for trading prediction markets on Polygon.
|
|
334
|
+
|
|
335
|
+
### 4. Polymarket Trading
|
|
336
|
+
|
|
337
|
+
#### Get Positions
|
|
338
|
+
|
|
339
|
+
Fetch all current positions for the session wallet:
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
const positions = await sdk.polymarket.positions();
|
|
343
|
+
|
|
344
|
+
if (positions.success && positions.data) {
|
|
345
|
+
console.log(`Total value: $${positions.data.totalValue}`);
|
|
346
|
+
|
|
347
|
+
for (const position of positions.data.positions) {
|
|
348
|
+
console.log(`${position.question} (${position.outcome})`);
|
|
349
|
+
console.log(` Shares: ${position.formattedShares}`);
|
|
350
|
+
console.log(` Value: $${position.valueUsd}`);
|
|
351
|
+
console.log(` P&L: $${position.pnlUsd} (${position.pnlPercent}%)`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### Place Market Orders
|
|
357
|
+
|
|
358
|
+
Execute buy or sell market orders:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// Buy order - size is USD amount to spend
|
|
362
|
+
const buyOrder = await sdk.polymarket.marketOrder({
|
|
363
|
+
tokenId: "123456789...", // Market token ID
|
|
364
|
+
size: 10, // Spend $10 to buy shares
|
|
365
|
+
side: "BUY"
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Sell order - size is number of shares to sell
|
|
369
|
+
const sellOrder = await sdk.polymarket.marketOrder({
|
|
370
|
+
tokenId: "123456789...",
|
|
371
|
+
size: 5.5, // Sell 5.5 shares
|
|
372
|
+
side: "SELL"
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
if (buyOrder.success && buyOrder.data) {
|
|
376
|
+
console.log(`Order ID: ${buyOrder.data.submitOrder.orderId}`);
|
|
377
|
+
|
|
378
|
+
if (buyOrder.data.orderInfo) {
|
|
379
|
+
console.log(`Filled at $${buyOrder.data.orderInfo.priceUsd} per share`);
|
|
380
|
+
console.log(`Total cost: $${buyOrder.data.orderInfo.totalPriceUsd}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### Redeem Positions
|
|
386
|
+
|
|
387
|
+
Claim winnings from settled positions:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
// Redeem all redeemable positions
|
|
391
|
+
const redemption = await sdk.polymarket.redeemPositions();
|
|
392
|
+
|
|
393
|
+
if (redemption.success && redemption.data) {
|
|
394
|
+
for (const result of redemption.data) {
|
|
395
|
+
if (result.success) {
|
|
396
|
+
console.log(`✅ Redeemed: ${result.position.question}`);
|
|
397
|
+
console.log(` TX: ${result.transactionHash}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Redeem specific positions by token IDs
|
|
403
|
+
const specificRedemption = await sdk.polymarket.redeemPositions({
|
|
404
|
+
tokenIds: ["123456", "789012"]
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Polymarket API Reference
|
|
409
|
+
|
|
410
|
+
#### `sdk.polymarket.positions(): Promise<PolymarketPositionsResponse>`
|
|
411
|
+
|
|
412
|
+
Get all current positions for the session wallet.
|
|
413
|
+
|
|
414
|
+
**Returns:**
|
|
415
|
+
```typescript
|
|
416
|
+
{
|
|
417
|
+
success: boolean,
|
|
418
|
+
data?: {
|
|
419
|
+
totalValue: number,
|
|
420
|
+
positions: Array<{
|
|
421
|
+
contractAddress: string,
|
|
422
|
+
tokenId: string,
|
|
423
|
+
question: string,
|
|
424
|
+
outcome: string,
|
|
425
|
+
formattedShares: string,
|
|
426
|
+
shares: string,
|
|
427
|
+
valueUsd: string,
|
|
428
|
+
priceUsd: string,
|
|
429
|
+
averagePriceUsd: string,
|
|
430
|
+
pnlUsd: string,
|
|
431
|
+
pnlPercent: string,
|
|
432
|
+
isRedeemable: boolean,
|
|
433
|
+
endDate: string,
|
|
434
|
+
// ... additional fields
|
|
435
|
+
}>
|
|
436
|
+
},
|
|
437
|
+
error?: string,
|
|
438
|
+
errorDetails?: { message: string, status?: number, statusText?: string }
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
#### `sdk.polymarket.marketOrder(request): Promise<PolymarketMarketOrderResponse>`
|
|
443
|
+
|
|
444
|
+
Place a buy or sell market order.
|
|
445
|
+
|
|
446
|
+
⚠️ **Important**: The `size` parameter meaning differs by order side:
|
|
447
|
+
- **BUY**: `size` is the USD amount to spend (e.g., 10 = $10 worth of shares)
|
|
448
|
+
- **SELL**: `size` is the number of shares/tokens to sell (e.g., 10 = 10 shares)
|
|
449
|
+
|
|
450
|
+
**Parameters:**
|
|
451
|
+
```typescript
|
|
452
|
+
{
|
|
453
|
+
tokenId: string, // Market token ID for the position
|
|
454
|
+
size: number, // For BUY: USD amount. For SELL: Number of shares
|
|
455
|
+
side: "BUY" | "SELL"
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Returns:**
|
|
460
|
+
```typescript
|
|
461
|
+
{
|
|
462
|
+
success: boolean,
|
|
463
|
+
data?: {
|
|
464
|
+
order: {
|
|
465
|
+
eip712Message: { /* EIP712 typed data */ },
|
|
466
|
+
order: { /* Order details */ }
|
|
467
|
+
},
|
|
468
|
+
submitOrder: {
|
|
469
|
+
orderId: string,
|
|
470
|
+
success: boolean,
|
|
471
|
+
errorMessage: string | null
|
|
472
|
+
},
|
|
473
|
+
orderInfo?: {
|
|
474
|
+
orderId: string,
|
|
475
|
+
priceUsd: string,
|
|
476
|
+
totalPriceUsd: string,
|
|
477
|
+
side: string,
|
|
478
|
+
size: string,
|
|
479
|
+
txHashes: string[]
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
error?: string,
|
|
483
|
+
errorDetails?: { message: string, status?: number, statusText?: string }
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
#### `sdk.polymarket.redeemPositions(request?): Promise<PolymarketRedeemPositionsResponse>`
|
|
488
|
+
|
|
489
|
+
Redeem settled positions to claim winnings.
|
|
490
|
+
|
|
491
|
+
**Parameters (optional):**
|
|
492
|
+
```typescript
|
|
493
|
+
{
|
|
494
|
+
tokenIds?: string[] // Specific token IDs to redeem (default: all redeemable positions)
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Returns:**
|
|
499
|
+
```typescript
|
|
500
|
+
{
|
|
501
|
+
success: boolean,
|
|
502
|
+
data?: Array<{
|
|
503
|
+
success: boolean,
|
|
504
|
+
position: { /* Full position details */ },
|
|
505
|
+
transactionHash: string | null
|
|
506
|
+
}>,
|
|
507
|
+
error?: string,
|
|
508
|
+
errorDetails?: { message: string, status?: number, statusText?: string }
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Complete Polymarket Example
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
516
|
+
const sdk = new AgentSdk({ sessionId: request.sessionId });
|
|
517
|
+
|
|
518
|
+
try {
|
|
519
|
+
// Get current positions
|
|
520
|
+
const positions = await sdk.polymarket.positions();
|
|
521
|
+
|
|
522
|
+
if (!positions.success || !positions.data) {
|
|
523
|
+
throw new Error(`Failed to get positions: ${positions.error}`);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Find specific position
|
|
527
|
+
const targetPosition = positions.data.positions.find(
|
|
528
|
+
p => p.tokenId === "YOUR_TOKEN_ID"
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
if (targetPosition && Number(targetPosition.formattedShares) > 0) {
|
|
532
|
+
// Sell position
|
|
533
|
+
const sellOrder = await sdk.polymarket.marketOrder({
|
|
534
|
+
tokenId: targetPosition.tokenId,
|
|
535
|
+
size: Number(targetPosition.formattedShares),
|
|
536
|
+
side: "SELL"
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
if (sellOrder.success && sellOrder.data?.orderInfo) {
|
|
540
|
+
await sdk.sendLog({
|
|
541
|
+
type: "observe",
|
|
542
|
+
shortMessage: `Sold ${targetPosition.outcome} for $${sellOrder.data.orderInfo.totalPriceUsd}`
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
return { success: true };
|
|
548
|
+
} catch (error) {
|
|
549
|
+
await sdk.sendLog({
|
|
550
|
+
type: "error",
|
|
551
|
+
shortMessage: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
552
|
+
});
|
|
553
|
+
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
const stopFunction: StopFunctionContract = async (request) => {
|
|
558
|
+
const sdk = new AgentSdk({ sessionId: request.sessionId });
|
|
559
|
+
|
|
560
|
+
try {
|
|
561
|
+
// Redeem all settled positions on stop
|
|
562
|
+
const redemption = await sdk.polymarket.redeemPositions();
|
|
563
|
+
|
|
564
|
+
if (redemption.success && redemption.data) {
|
|
565
|
+
const successful = redemption.data.filter(r => r.success);
|
|
566
|
+
await sdk.sendLog({
|
|
567
|
+
type: "observe",
|
|
568
|
+
shortMessage: `✅ Redeemed ${successful.length} positions`
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return { success: true };
|
|
573
|
+
} catch (error) {
|
|
574
|
+
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
|
|
330
580
|
## 🔧 Examples
|
|
331
581
|
|
|
332
582
|
### Barebones Agent
|
package/index.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ declare const EIP712TypedDataSchema: z.ZodObject<{
|
|
|
66
66
|
type: z.ZodString;
|
|
67
67
|
}, z.core.$strip>>>;
|
|
68
68
|
primaryType: z.ZodString;
|
|
69
|
-
message: z.ZodRecord<z.ZodString, z.
|
|
69
|
+
message: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
70
70
|
}, z.core.$strip>;
|
|
71
71
|
/**
|
|
72
72
|
* EIP191 Message schema for simple message signing
|
|
@@ -229,9 +229,9 @@ declare const SwidgeExecuteRequestSchema: z.ZodObject<{
|
|
|
229
229
|
chainId: z.ZodNumber;
|
|
230
230
|
value: z.ZodNumber;
|
|
231
231
|
data: z.ZodString;
|
|
232
|
-
gas: z.ZodNumber
|
|
233
|
-
maxFeePerGas: z.ZodNumber
|
|
234
|
-
maxPriorityFeePerGas: z.ZodNumber
|
|
232
|
+
gas: z.ZodOptional<z.ZodNumber>;
|
|
233
|
+
maxFeePerGas: z.ZodOptional<z.ZodNumber>;
|
|
234
|
+
maxPriorityFeePerGas: z.ZodOptional<z.ZodNumber>;
|
|
235
235
|
}, z.core.$strip>, z.ZodObject<{
|
|
236
236
|
type: z.ZodLiteral<"solana">;
|
|
237
237
|
instructions: z.ZodArray<z.ZodObject<{
|
|
@@ -321,9 +321,9 @@ declare const SwidgeQuoteResponseWrapperSchema: z.ZodObject<{
|
|
|
321
321
|
chainId: z.ZodNumber;
|
|
322
322
|
value: z.ZodNumber;
|
|
323
323
|
data: z.ZodString;
|
|
324
|
-
gas: z.ZodNumber
|
|
325
|
-
maxFeePerGas: z.ZodNumber
|
|
326
|
-
maxPriorityFeePerGas: z.ZodNumber
|
|
324
|
+
gas: z.ZodOptional<z.ZodNumber>;
|
|
325
|
+
maxFeePerGas: z.ZodOptional<z.ZodNumber>;
|
|
326
|
+
maxPriorityFeePerGas: z.ZodOptional<z.ZodNumber>;
|
|
327
327
|
}, z.core.$strip>, z.ZodObject<{
|
|
328
328
|
type: z.ZodLiteral<"solana">;
|
|
329
329
|
instructions: z.ZodArray<z.ZodObject<{
|
|
@@ -380,6 +380,166 @@ type SwidgeQuoteResponse = z.infer<typeof SwidgeQuoteResponseWrapperSchema>;
|
|
|
380
380
|
type SwidgeExecuteRequest = z.infer<typeof SwidgeExecuteRequestSchema>;
|
|
381
381
|
type SwidgeExecuteResponse = z.infer<typeof SwidgeExecuteResponseWrapperSchema>;
|
|
382
382
|
|
|
383
|
+
declare const PolymarketPositionSchema: z.ZodObject<{
|
|
384
|
+
contractAddress: z.ZodString;
|
|
385
|
+
tokenId: z.ZodNullable<z.ZodString>;
|
|
386
|
+
decimals: z.ZodNumber;
|
|
387
|
+
conditionId: z.ZodString;
|
|
388
|
+
formattedShares: z.ZodString;
|
|
389
|
+
shares: z.ZodString;
|
|
390
|
+
valueUsd: z.ZodString;
|
|
391
|
+
question: z.ZodString;
|
|
392
|
+
outcome: z.ZodString;
|
|
393
|
+
priceUsd: z.ZodString;
|
|
394
|
+
averagePriceUsd: z.ZodString;
|
|
395
|
+
isRedeemable: z.ZodBoolean;
|
|
396
|
+
imageUrl: z.ZodString;
|
|
397
|
+
initialValue: z.ZodString;
|
|
398
|
+
pnlUsd: z.ZodString;
|
|
399
|
+
pnlPercent: z.ZodString;
|
|
400
|
+
pnlRealizedUsd: z.ZodString;
|
|
401
|
+
pnlRealizedPercent: z.ZodString;
|
|
402
|
+
endDate: z.ZodString;
|
|
403
|
+
}, z.core.$strip>;
|
|
404
|
+
declare const PolymarketMarketOrderRequestSchema: z.ZodObject<{
|
|
405
|
+
tokenId: z.ZodString;
|
|
406
|
+
size: z.ZodNumber;
|
|
407
|
+
side: z.ZodEnum<{
|
|
408
|
+
BUY: "BUY";
|
|
409
|
+
SELL: "SELL";
|
|
410
|
+
}>;
|
|
411
|
+
}, z.core.$strip>;
|
|
412
|
+
declare const PolymarketRedeemPositionsRequestSchema: z.ZodObject<{
|
|
413
|
+
tokenIds: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
414
|
+
}, z.core.$strip>;
|
|
415
|
+
declare const PolymarketPositionsResponseSchema: z.ZodObject<{
|
|
416
|
+
success: z.ZodBoolean;
|
|
417
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
418
|
+
totalValue: z.ZodNumber;
|
|
419
|
+
positions: z.ZodArray<z.ZodObject<{
|
|
420
|
+
contractAddress: z.ZodString;
|
|
421
|
+
tokenId: z.ZodNullable<z.ZodString>;
|
|
422
|
+
decimals: z.ZodNumber;
|
|
423
|
+
conditionId: z.ZodString;
|
|
424
|
+
formattedShares: z.ZodString;
|
|
425
|
+
shares: z.ZodString;
|
|
426
|
+
valueUsd: z.ZodString;
|
|
427
|
+
question: z.ZodString;
|
|
428
|
+
outcome: z.ZodString;
|
|
429
|
+
priceUsd: z.ZodString;
|
|
430
|
+
averagePriceUsd: z.ZodString;
|
|
431
|
+
isRedeemable: z.ZodBoolean;
|
|
432
|
+
imageUrl: z.ZodString;
|
|
433
|
+
initialValue: z.ZodString;
|
|
434
|
+
pnlUsd: z.ZodString;
|
|
435
|
+
pnlPercent: z.ZodString;
|
|
436
|
+
pnlRealizedUsd: z.ZodString;
|
|
437
|
+
pnlRealizedPercent: z.ZodString;
|
|
438
|
+
endDate: z.ZodString;
|
|
439
|
+
}, z.core.$strip>>;
|
|
440
|
+
}, z.core.$strip>>;
|
|
441
|
+
error: z.ZodOptional<z.ZodString>;
|
|
442
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
443
|
+
message: z.ZodString;
|
|
444
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
445
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
446
|
+
}, z.core.$strip>>;
|
|
447
|
+
}, z.core.$strip>;
|
|
448
|
+
declare const PolymarketMarketOrderResponseSchema: z.ZodObject<{
|
|
449
|
+
success: z.ZodBoolean;
|
|
450
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
451
|
+
order: z.ZodObject<{
|
|
452
|
+
eip712Message: z.ZodObject<{
|
|
453
|
+
types: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
|
|
454
|
+
name: z.ZodString;
|
|
455
|
+
type: z.ZodString;
|
|
456
|
+
}, z.core.$strip>>>;
|
|
457
|
+
domain: z.ZodObject<{
|
|
458
|
+
name: z.ZodString;
|
|
459
|
+
version: z.ZodString;
|
|
460
|
+
chainId: z.ZodNumber;
|
|
461
|
+
verifyingContract: z.ZodString;
|
|
462
|
+
}, z.core.$strip>;
|
|
463
|
+
primaryType: z.ZodString;
|
|
464
|
+
message: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
465
|
+
}, z.core.$strip>;
|
|
466
|
+
order: z.ZodObject<{
|
|
467
|
+
salt: z.ZodString;
|
|
468
|
+
maker: z.ZodString;
|
|
469
|
+
signer: z.ZodString;
|
|
470
|
+
taker: z.ZodString;
|
|
471
|
+
tokenId: z.ZodString;
|
|
472
|
+
makerAmount: z.ZodString;
|
|
473
|
+
takerAmount: z.ZodString;
|
|
474
|
+
expiration: z.ZodString;
|
|
475
|
+
nonce: z.ZodString;
|
|
476
|
+
feeRateBps: z.ZodString;
|
|
477
|
+
side: z.ZodNumber;
|
|
478
|
+
signatureType: z.ZodNumber;
|
|
479
|
+
}, z.core.$strip>;
|
|
480
|
+
}, z.core.$strip>;
|
|
481
|
+
submitOrder: z.ZodObject<{
|
|
482
|
+
orderId: z.ZodString;
|
|
483
|
+
success: z.ZodBoolean;
|
|
484
|
+
errorMessage: z.ZodOptional<z.ZodString>;
|
|
485
|
+
}, z.core.$strip>;
|
|
486
|
+
orderInfo: z.ZodOptional<z.ZodObject<{
|
|
487
|
+
orderId: z.ZodString;
|
|
488
|
+
side: z.ZodString;
|
|
489
|
+
size: z.ZodString;
|
|
490
|
+
priceUsd: z.ZodString;
|
|
491
|
+
totalPriceUsd: z.ZodString;
|
|
492
|
+
txHashes: z.ZodArray<z.ZodString>;
|
|
493
|
+
}, z.core.$strip>>;
|
|
494
|
+
}, z.core.$strip>>;
|
|
495
|
+
error: z.ZodOptional<z.ZodString>;
|
|
496
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
497
|
+
message: z.ZodString;
|
|
498
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
499
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
500
|
+
}, z.core.$strip>>;
|
|
501
|
+
}, z.core.$strip>;
|
|
502
|
+
declare const PolymarketRedeemPositionsResponseSchema: z.ZodObject<{
|
|
503
|
+
success: z.ZodBoolean;
|
|
504
|
+
data: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
505
|
+
success: z.ZodBoolean;
|
|
506
|
+
position: z.ZodObject<{
|
|
507
|
+
contractAddress: z.ZodString;
|
|
508
|
+
tokenId: z.ZodNullable<z.ZodString>;
|
|
509
|
+
decimals: z.ZodNumber;
|
|
510
|
+
conditionId: z.ZodString;
|
|
511
|
+
formattedShares: z.ZodString;
|
|
512
|
+
shares: z.ZodString;
|
|
513
|
+
valueUsd: z.ZodString;
|
|
514
|
+
question: z.ZodString;
|
|
515
|
+
outcome: z.ZodString;
|
|
516
|
+
priceUsd: z.ZodString;
|
|
517
|
+
averagePriceUsd: z.ZodString;
|
|
518
|
+
isRedeemable: z.ZodBoolean;
|
|
519
|
+
imageUrl: z.ZodString;
|
|
520
|
+
initialValue: z.ZodString;
|
|
521
|
+
pnlUsd: z.ZodString;
|
|
522
|
+
pnlPercent: z.ZodString;
|
|
523
|
+
pnlRealizedUsd: z.ZodString;
|
|
524
|
+
pnlRealizedPercent: z.ZodString;
|
|
525
|
+
endDate: z.ZodString;
|
|
526
|
+
}, z.core.$strip>;
|
|
527
|
+
transactionHash: z.ZodNullable<z.ZodString>;
|
|
528
|
+
}, z.core.$strip>>>;
|
|
529
|
+
error: z.ZodOptional<z.ZodString>;
|
|
530
|
+
errorDetails: z.ZodOptional<z.ZodObject<{
|
|
531
|
+
message: z.ZodString;
|
|
532
|
+
status: z.ZodOptional<z.ZodNumber>;
|
|
533
|
+
statusText: z.ZodOptional<z.ZodString>;
|
|
534
|
+
}, z.core.$strip>>;
|
|
535
|
+
}, z.core.$strip>;
|
|
536
|
+
type PolymarketPosition = z.infer<typeof PolymarketPositionSchema>;
|
|
537
|
+
type PolymarketMarketOrderRequest = z.infer<typeof PolymarketMarketOrderRequestSchema>;
|
|
538
|
+
type PolymarketRedeemPositionsRequest = z.infer<typeof PolymarketRedeemPositionsRequestSchema>;
|
|
539
|
+
type PolymarketPositionsResponse = z.infer<typeof PolymarketPositionsResponseSchema>;
|
|
540
|
+
type PolymarketMarketOrderResponse = z.infer<typeof PolymarketMarketOrderResponseSchema>;
|
|
541
|
+
type PolymarketRedeemPositionsResponse = z.infer<typeof PolymarketRedeemPositionsResponseSchema>;
|
|
542
|
+
|
|
383
543
|
/**
|
|
384
544
|
* Main AgentSdk class with simplified API surface
|
|
385
545
|
*/
|
|
@@ -649,6 +809,208 @@ declare class AgentSdk {
|
|
|
649
809
|
*/
|
|
650
810
|
execute: (executeQuote: SwidgeExecuteRequest) => Promise<SwidgeExecuteResponse>;
|
|
651
811
|
};
|
|
812
|
+
/**
|
|
813
|
+
* 📈 Polymarket: Trade prediction markets seamlessly
|
|
814
|
+
*
|
|
815
|
+
* Access Polymarket positions, execute market orders, and redeem positions using your
|
|
816
|
+
* session wallet. All operations are policy-checked and signed automatically.
|
|
817
|
+
*/
|
|
818
|
+
readonly polymarket: {
|
|
819
|
+
/**
|
|
820
|
+
* Get current positions on Polymarket
|
|
821
|
+
*
|
|
822
|
+
* Fetches all open positions for the session wallet, including value, PNL, and market details.
|
|
823
|
+
*
|
|
824
|
+
* @returns Wrapped response with positions array and total value
|
|
825
|
+
* @example
|
|
826
|
+
* // Usage
|
|
827
|
+
* const result = await sdk.polymarket.positions();
|
|
828
|
+
*
|
|
829
|
+
* if (result.success && result.data) {
|
|
830
|
+
* console.log(`Total portfolio value: $${result.data.totalValue}`);
|
|
831
|
+
* result.data.positions.forEach(pos => {
|
|
832
|
+
* console.log(`${pos.question} - ${pos.outcome}: $${pos.valueUsd} (PNL: ${pos.pnlUsd})`);
|
|
833
|
+
* });
|
|
834
|
+
* } else {
|
|
835
|
+
* console.log(`Error: ${result.error}`);
|
|
836
|
+
* }
|
|
837
|
+
*
|
|
838
|
+
* // Input: None (GET request)
|
|
839
|
+
*
|
|
840
|
+
* // Output showcase (success case):
|
|
841
|
+
* {
|
|
842
|
+
* success: true,
|
|
843
|
+
* data: {
|
|
844
|
+
* totalValue: 150.75,
|
|
845
|
+
* positions: [
|
|
846
|
+
* {
|
|
847
|
+
* contractAddress: "0x...",
|
|
848
|
+
* tokenId: "123456",
|
|
849
|
+
* decimals: 6,
|
|
850
|
+
* conditionId: "0x...",
|
|
851
|
+
* formattedShares: "10.0",
|
|
852
|
+
* shares: "10000000",
|
|
853
|
+
* valueUsd: "10.5",
|
|
854
|
+
* question: "Will event X happen?",
|
|
855
|
+
* outcome: "Yes",
|
|
856
|
+
* priceUsd: "1.05",
|
|
857
|
+
* averagePriceUsd: "0.95",
|
|
858
|
+
* isRedeemable: false,
|
|
859
|
+
* imageUrl: "https://...",
|
|
860
|
+
* initialValue: "9.5",
|
|
861
|
+
* pnlUsd: "1.0",
|
|
862
|
+
* pnlPercent: "10.53",
|
|
863
|
+
* pnlRealizedUsd: "0",
|
|
864
|
+
* pnlRealizedPercent: "0",
|
|
865
|
+
* endDate: "2024-12-31"
|
|
866
|
+
* },
|
|
867
|
+
* // ... more positions
|
|
868
|
+
* ]
|
|
869
|
+
* }
|
|
870
|
+
* }
|
|
871
|
+
*
|
|
872
|
+
* // Error case:
|
|
873
|
+
* {
|
|
874
|
+
* success: false,
|
|
875
|
+
* error: "Could not get positions",
|
|
876
|
+
* errorDetails: { message: "Wallet not found", status: 400 }
|
|
877
|
+
* }
|
|
878
|
+
*/
|
|
879
|
+
positions: () => Promise<PolymarketPositionsResponse>;
|
|
880
|
+
/**
|
|
881
|
+
* Execute a market order on Polymarket
|
|
882
|
+
*
|
|
883
|
+
* Places a buy or sell market order for the specified token and size. Handles approvals,
|
|
884
|
+
* signing, and submission automatically.
|
|
885
|
+
*
|
|
886
|
+
* ⚠️ **Important**: The `size` parameter meaning differs by order side:
|
|
887
|
+
* - **BUY**: `size` is the USD amount to spend (e.g., 10 = $10 worth of shares)
|
|
888
|
+
* - **SELL**: `size` is the number of shares/tokens to sell (e.g., 10 = 10 shares)
|
|
889
|
+
*
|
|
890
|
+
* @param request Order parameters
|
|
891
|
+
* @param request.tokenId Market token ID for the position
|
|
892
|
+
* @param request.size For BUY: USD amount to spend. For SELL: Number of shares to sell
|
|
893
|
+
* @param request.side "BUY" or "SELL"
|
|
894
|
+
* @returns Wrapped response with order details and submission result
|
|
895
|
+
* @example
|
|
896
|
+
* // BUY order - size is USD amount
|
|
897
|
+
* const buyResult = await sdk.polymarket.marketOrder({
|
|
898
|
+
* tokenId: "123456",
|
|
899
|
+
* size: 10, // Spend $10 to buy shares
|
|
900
|
+
* side: "BUY"
|
|
901
|
+
* });
|
|
902
|
+
*
|
|
903
|
+
* // SELL order - size is number of shares
|
|
904
|
+
* const sellResult = await sdk.polymarket.marketOrder({
|
|
905
|
+
* tokenId: "123456",
|
|
906
|
+
* size: 5, // Sell 5 shares
|
|
907
|
+
* side: "SELL"
|
|
908
|
+
* });
|
|
909
|
+
*
|
|
910
|
+
* if (buyResult.success && buyResult.data) {
|
|
911
|
+
* console.log(`Order ID: ${buyResult.data.submitOrder.orderId}`);
|
|
912
|
+
* console.log(`Success: ${buyResult.data.submitOrder.success}`);
|
|
913
|
+
* } else {
|
|
914
|
+
* console.log(`Error: ${buyResult.error}`);
|
|
915
|
+
* }
|
|
916
|
+
*
|
|
917
|
+
* // Input showcase:
|
|
918
|
+
* {
|
|
919
|
+
* tokenId: "123456", // Market token ID
|
|
920
|
+
* size: 10, // BUY: USD amount ($10) | SELL: Number of shares (10 shares)
|
|
921
|
+
* side: "BUY" // or "SELL"
|
|
922
|
+
* }
|
|
923
|
+
*
|
|
924
|
+
* // Output showcase (success case):
|
|
925
|
+
* {
|
|
926
|
+
* success: true,
|
|
927
|
+
* data: {
|
|
928
|
+
* order: {
|
|
929
|
+
* eip712Message: {
|
|
930
|
+
* // Typed data for signing (domain, types, message)
|
|
931
|
+
* },
|
|
932
|
+
* order: {
|
|
933
|
+
* salt: "123456789",
|
|
934
|
+
* maker: "0x...",
|
|
935
|
+
* signer: "0x...",
|
|
936
|
+
* taker: "0x...",
|
|
937
|
+
* tokenId: "123456",
|
|
938
|
+
* makerAmount: "105000000", // USD amount in USDC decimals
|
|
939
|
+
* takerAmount: "10000000", // Shares in decimals
|
|
940
|
+
* expiration: "0",
|
|
941
|
+
* nonce: "0",
|
|
942
|
+
* feeRateBps: "0",
|
|
943
|
+
* side: 0, // 0 = BUY, 1 = SELL
|
|
944
|
+
* signatureType: 0 // 0 = EIP712
|
|
945
|
+
* }
|
|
946
|
+
* },
|
|
947
|
+
* submitOrder: {
|
|
948
|
+
* orderId: "abc123",
|
|
949
|
+
* success: true,
|
|
950
|
+
* errorMessage: ""
|
|
951
|
+
* }
|
|
952
|
+
* }
|
|
953
|
+
* }
|
|
954
|
+
*
|
|
955
|
+
* // Error case:
|
|
956
|
+
* {
|
|
957
|
+
* success: false,
|
|
958
|
+
* error: "Could not get order",
|
|
959
|
+
* errorDetails: { message: "Invalid request", status: 400 }
|
|
960
|
+
* }
|
|
961
|
+
*/
|
|
962
|
+
marketOrder: (request: PolymarketMarketOrderRequest) => Promise<PolymarketMarketOrderResponse>;
|
|
963
|
+
/**
|
|
964
|
+
* Redeem settled positions on Polymarket
|
|
965
|
+
*
|
|
966
|
+
* Redeems one or all redeemable positions, claiming winnings. Handles multiple transactions if needed.
|
|
967
|
+
*
|
|
968
|
+
* @param request Redemption parameters (omit to redeem all, or pass tokenIds for specific positions)
|
|
969
|
+
* @returns Wrapped response with per-position redemption results
|
|
970
|
+
* @example
|
|
971
|
+
* // Redeem all positions (no arguments - default behavior)
|
|
972
|
+
* const allResult = await sdk.polymarket.redeemPositions();
|
|
973
|
+
*
|
|
974
|
+
* // Redeem specific positions
|
|
975
|
+
* const specificResult = await sdk.polymarket.redeemPositions({ tokenIds: ["123456", "789012"] });
|
|
976
|
+
*
|
|
977
|
+
* if (result.success && result.data) {
|
|
978
|
+
* result.data.forEach(tx => {
|
|
979
|
+
* if (tx.success) {
|
|
980
|
+
* console.log(`Redeemed ${tx.position.question}: Tx ${tx.transactionHash}`);
|
|
981
|
+
* }
|
|
982
|
+
* });
|
|
983
|
+
* }
|
|
984
|
+
*
|
|
985
|
+
* // Input showcase:
|
|
986
|
+
* // No arguments - redeem all positions (default)
|
|
987
|
+
* // or
|
|
988
|
+
* { tokenIds: ["123456", "789012"] } // Redeem specific positions
|
|
989
|
+
*
|
|
990
|
+
* // Output showcase (success case):
|
|
991
|
+
* {
|
|
992
|
+
* success: true,
|
|
993
|
+
* data: [
|
|
994
|
+
* {
|
|
995
|
+
* success: true,
|
|
996
|
+
* position: {
|
|
997
|
+
* // Full position details as in positions response
|
|
998
|
+
* },
|
|
999
|
+
* transactionHash: "0xabc123..."
|
|
1000
|
+
* },
|
|
1001
|
+
* // ... more redemptions
|
|
1002
|
+
* ]
|
|
1003
|
+
* }
|
|
1004
|
+
*
|
|
1005
|
+
* // Error case:
|
|
1006
|
+
* {
|
|
1007
|
+
* success: false,
|
|
1008
|
+
* error: "Could not get positions",
|
|
1009
|
+
* errorDetails: { message: "No redeemable positions", status: 404 }
|
|
1010
|
+
* }
|
|
1011
|
+
*/
|
|
1012
|
+
redeemPositions: (request?: PolymarketRedeemPositionsRequest) => Promise<PolymarketRedeemPositionsResponse>;
|
|
1013
|
+
};
|
|
652
1014
|
/**
|
|
653
1015
|
* Handle EVM transaction signing and broadcasting
|
|
654
1016
|
*/
|
|
@@ -680,6 +1042,9 @@ declare class AgentSdk {
|
|
|
680
1042
|
* Handle swidge execute requests
|
|
681
1043
|
*/
|
|
682
1044
|
private handleSwidgeExecute;
|
|
1045
|
+
private handlePolymarketPositions;
|
|
1046
|
+
private handlePolymarketMarketOrder;
|
|
1047
|
+
private handlePolymarketRedeemPositions;
|
|
683
1048
|
}
|
|
684
1049
|
|
|
685
1050
|
/**
|
|
@@ -954,4 +1319,4 @@ declare function isSolanaNetwork(network: Network): network is "solana";
|
|
|
954
1319
|
*/
|
|
955
1320
|
declare function getChainIdFromNetwork(network: `ethereum:${number}`): number;
|
|
956
1321
|
|
|
957
|
-
export { APIClient, Agent, AgentSdk, type ExecutionFunctionContract, type Network, 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 };
|
|
1322
|
+
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 };
|
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.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)};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}}}}};import{zValidator}from"@hono/zod-validator";import{Hono}from"hono";import{cors}from"hono/cors";import{z}from"zod";var AgentRequestSchema=z.object({sessionId:z.number(),sessionWalletAddress:z.string(),jobId:z.string().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(),maxFeePerGas:z2.number(),maxPriorityFeePerGas:z2.number()}),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})}};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:{order:{eip712Message:{types:{},domain:{name:"test",version:"1",chainId:137,verifyingContract:"0x0000000000000000000000000000000000000000"},primaryType:"Order",message:{}},order:{salt:"0",maker:"0x0000000000000000000000000000000000000000",signer:"0x0000000000000000000000000000000000000000",taker:"0x0000000000000000000000000000000000000000",tokenId:"test-token-id",makerAmount:"0",takerAmount:"0",expiration:"0",nonce:"0",feeRateBps:"0",side:0,signatureType:0}},submitOrder:{orderId:"test-order-id",success:!0}}}:{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 AgentRequestSchema=z.object({sessionId:z.number(),sessionWalletAddress:z.string(),jobId:z.string().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};
|