@circuitorg/agent-sdk 1.2.0 → 1.2.3
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 +83 -1
- package/chunk-4I3A6QAK.js +1 -0
- package/index.d.ts +439 -17
- package/index.js +1 -1
- package/package.json +1 -1
- package/utils/auth-loader.d.ts +6 -0
- package/utils/auth-loader.js +1 -0
- package/utils/auth-loader.cjs +0 -39
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ A simplified TypeScript SDK for building automated agents to deploy on Circuit.
|
|
|
13
13
|
- [🚀 Quick Start](#-quick-start)
|
|
14
14
|
- [Install the SDK](#install-the-sdk)
|
|
15
15
|
- [Create Your First Agent](#create-your-first-agent)
|
|
16
|
+
- [Required Asset setup](#required-asset-setup)
|
|
16
17
|
- [🎯 Core Concepts](#-core-concepts)
|
|
17
18
|
- [The AgentContext Object](#the-agentcontext-object)
|
|
18
19
|
- [Run/Stop Function Requirements](#runstop-function-requirements)
|
|
@@ -23,6 +24,7 @@ A simplified TypeScript SDK for building automated agents to deploy on Circuit.
|
|
|
23
24
|
- [📈 Polymarket Prediction Markets](#-polymarket-prediction-markets)
|
|
24
25
|
- [Place Market Orders](#place-market-orders)
|
|
25
26
|
- [Redeem Positions](#redeem-positions)
|
|
27
|
+
- [📊 Transaction History](#-transaction-history)
|
|
26
28
|
- [🚀 Sign \& Send Transactions](#-sign--send-transactions)
|
|
27
29
|
- [Ethereum (any EVM chain)](#ethereum-any-evm-chain)
|
|
28
30
|
- [Solana](#solana)
|
|
@@ -65,9 +67,27 @@ Every agent receives a single `AgentContext` object that provides:
|
|
|
65
67
|
- `agent.swidge` - Cross-chain swaps and bridges (`.quote()`, `.execute()`)
|
|
66
68
|
- `agent.signAndSend()` - Execute custom built transactions on any supported chain
|
|
67
69
|
- `agent.signMessage()` - Sign messages (EVM only)
|
|
70
|
+
- `agent.transactions()` - Get transaction history with asset changes
|
|
68
71
|
|
|
69
72
|
**Important:** `currentPositions` reflects your allocated assets at the **start** of each execution. To avoid failed transactions, you should be tracking intra-run position changes based on transactions the agent makes during the execution. Circuit will provide updated positions on the next execution request.
|
|
70
73
|
|
|
74
|
+
|
|
75
|
+
#### Required Asset setup
|
|
76
|
+
> Note: For native tokens, use the following null addresses for solana/ethereum
|
|
77
|
+
```toml
|
|
78
|
+
// Requiring 1 SOL
|
|
79
|
+
[[requiredAssets]]
|
|
80
|
+
network = "solana"
|
|
81
|
+
address = "11111111111111111111111111111111"
|
|
82
|
+
minimumAmount = "1000000000"
|
|
83
|
+
|
|
84
|
+
// Requiring 1 ETH
|
|
85
|
+
[[requiredAssets]]
|
|
86
|
+
network = "ethereum:<chainId>"
|
|
87
|
+
address = "0x0000000000000000000000000000000000000000"
|
|
88
|
+
minimumAmount = "1000000000000000000"
|
|
89
|
+
```
|
|
90
|
+
|
|
71
91
|
```typescript
|
|
72
92
|
import { Agent, AgentContext } from "@circuitorg/agent-sdk";
|
|
73
93
|
|
|
@@ -121,6 +141,7 @@ Every agent function receives a single `AgentContext` object that contains:
|
|
|
121
141
|
- `agent.swidge` - Cross-chain swap operations
|
|
122
142
|
- `agent.signAndSend()` - Sign and broadcast transactions
|
|
123
143
|
- `agent.signMessage()` - Sign messages on EVM
|
|
144
|
+
- `agent.transactions()` - Get transaction history with asset changes
|
|
124
145
|
|
|
125
146
|
### Run/Stop Function Requirements
|
|
126
147
|
|
|
@@ -215,6 +236,8 @@ Built-in Swidge integration for seamless cross-chain token swaps and bridges.
|
|
|
215
236
|
### Get and execute a quote
|
|
216
237
|
> Note: It is important to always validate quotes before executing. Circuit will always do its best to return a quote, and as of now, will only filter out quotes with price impacts exceeding 100% to ensure maximum flexibility. It is on the agent to makes sure a quote is valid, given its own parameters
|
|
217
238
|
|
|
239
|
+
> **Bulk Execution:** `execute()` accepts both single quotes and arrays. Pass an array to execute multiple swaps in parallel: `await agent.swidge.execute([quote1.data, quote2.data])` returns an array of results.
|
|
240
|
+
|
|
218
241
|
```typescript
|
|
219
242
|
async function run(agent: AgentContext): Promise<void> {
|
|
220
243
|
// 1. Get quote
|
|
@@ -224,7 +247,6 @@ async function run(agent: AgentContext): Promise<void> {
|
|
|
224
247
|
amount: "1000000000000000", // 0.001 ETH
|
|
225
248
|
toToken: "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
|
|
226
249
|
slippage: "2.0",
|
|
227
|
-
priceImpact: "100.0"
|
|
228
250
|
});
|
|
229
251
|
|
|
230
252
|
if (!quote.success) {
|
|
@@ -306,6 +328,66 @@ async function stop(agent: AgentContext): Promise<void> {
|
|
|
306
328
|
}
|
|
307
329
|
```
|
|
308
330
|
|
|
331
|
+
## 📊 Transaction History
|
|
332
|
+
|
|
333
|
+
Get a list of asset changes for all confirmed transactions during your session. This is useful for tracking what assets have moved in and out of the agent's wallet.
|
|
334
|
+
|
|
335
|
+
> **Note:** The system needs to index new transactions, so there may be a slight delay between when you execute a transaction and when the resulting asset changes are returned in this method. Make sure you are taking that into consideration if dealing with assets the agent just transacted with.
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
async function run(agent: AgentContext): Promise<void> {
|
|
339
|
+
// Get all transaction history for this session
|
|
340
|
+
const result = await agent.transactions();
|
|
341
|
+
|
|
342
|
+
if (result.success && result.data) {
|
|
343
|
+
await agent.log(`Found ${result.data.length} asset changes`);
|
|
344
|
+
|
|
345
|
+
// Filter for outgoing transfers
|
|
346
|
+
const outgoing = result.data.filter(
|
|
347
|
+
(change) => change.from === agent.sessionWalletAddress
|
|
348
|
+
);
|
|
349
|
+
await agent.log(`Outgoing transfers: ${outgoing.length}`);
|
|
350
|
+
|
|
351
|
+
// Calculate total USD value (where price data is available)
|
|
352
|
+
const totalUsd = result.data
|
|
353
|
+
.filter((c) => c.tokenUsdPrice)
|
|
354
|
+
.reduce((sum, c) => {
|
|
355
|
+
const amount = parseFloat(c.amount);
|
|
356
|
+
const price = parseFloat(c.tokenUsdPrice!);
|
|
357
|
+
return sum + amount * price;
|
|
358
|
+
}, 0);
|
|
359
|
+
await agent.log(`Total USD value: $${totalUsd.toFixed(2)}`);
|
|
360
|
+
|
|
361
|
+
// View specific transaction details
|
|
362
|
+
for (const change of result.data) {
|
|
363
|
+
await agent.log(`${change.network}: ${change.from} → ${change.to}`);
|
|
364
|
+
await agent.log(` Amount: ${change.amount} ${change.tokenType}`);
|
|
365
|
+
if (change.token) {
|
|
366
|
+
await agent.log(` Token: ${change.token}`);
|
|
367
|
+
}
|
|
368
|
+
await agent.log(` Tx: ${change.transactionHash}`);
|
|
369
|
+
await agent.log(` Time: ${change.timestamp}`);
|
|
370
|
+
}
|
|
371
|
+
} else {
|
|
372
|
+
await agent.log(result.error || "Failed to fetch transactions", { error: true });
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**AssetChange Structure:**
|
|
378
|
+
|
|
379
|
+
Each asset change in the response contains:
|
|
380
|
+
- `network` - Network identifier (e.g., `"ethereum:1"`, `"solana"`)
|
|
381
|
+
- `transactionHash` - Transaction hash
|
|
382
|
+
- `from` - Sender address
|
|
383
|
+
- `to` - Recipient address
|
|
384
|
+
- `amount` - Amount transferred (as string to preserve precision)
|
|
385
|
+
- `token` - Token contract address (`null` for native tokens)
|
|
386
|
+
- `tokenId` - Token ID for NFTs (`null` for fungible tokens)
|
|
387
|
+
- `tokenType` - Token type (e.g., `"native"`, `"ERC20"`, `"ERC721"`)
|
|
388
|
+
- `tokenUsdPrice` - Token price in USD at time of transaction (`null` if unavailable)
|
|
389
|
+
- `timestamp` - Transaction timestamp
|
|
390
|
+
|
|
309
391
|
## 🚀 Sign & Send Transactions
|
|
310
392
|
|
|
311
393
|
### Ethereum (any EVM chain)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as t,readFileSync as r}from"fs";import{homedir as o}from"os";import{join as n}from"path";function i(){try{if("undefined"==typeof process)return;const i=o();let c=n(i,".config","circuit","auth.json");if(!t(c)&&(c=n(i,".circuit","auth.json"),!t(c)))return;const f=r(c,"utf-8");return JSON.parse(f)}catch{return}}export{i as loadAuthFromFileSystem};
|
package/index.d.ts
CHANGED
|
@@ -139,6 +139,137 @@ type SignMessageResponse = {
|
|
|
139
139
|
statusText?: string;
|
|
140
140
|
};
|
|
141
141
|
};
|
|
142
|
+
/**
|
|
143
|
+
* Asset change representing a token transfer in a confirmed transaction
|
|
144
|
+
*/
|
|
145
|
+
type AssetChange = {
|
|
146
|
+
/** Network identifier (e.g., "ethereum:1", "solana") */
|
|
147
|
+
network: string;
|
|
148
|
+
/** Transaction hash */
|
|
149
|
+
transactionHash: string;
|
|
150
|
+
/** Sender address */
|
|
151
|
+
from: string;
|
|
152
|
+
/** Recipient address */
|
|
153
|
+
to: string;
|
|
154
|
+
/** Amount transferred (as string to preserve precision) */
|
|
155
|
+
amount: string;
|
|
156
|
+
/** Token contract address (null for native tokens) */
|
|
157
|
+
token: string | null;
|
|
158
|
+
/** Token ID for NFTs (null for fungible tokens) */
|
|
159
|
+
tokenId: string | null;
|
|
160
|
+
/** Token type (e.g., "native", "ERC20", "ERC721") */
|
|
161
|
+
tokenType: string;
|
|
162
|
+
/** Token price in USD at time of transaction (null if unavailable) */
|
|
163
|
+
tokenUsdPrice: string | null;
|
|
164
|
+
/** Timestamp of the transaction */
|
|
165
|
+
timestamp: string;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Response from transactions() method
|
|
169
|
+
*/
|
|
170
|
+
type TransactionsResponse = {
|
|
171
|
+
/** Whether the operation was successful */
|
|
172
|
+
success: boolean;
|
|
173
|
+
/** Array of asset changes (only present on success) */
|
|
174
|
+
data?: AssetChange[];
|
|
175
|
+
/** Error message (only present on failure) */
|
|
176
|
+
error?: string;
|
|
177
|
+
/** Detailed error message (only present on failure) */
|
|
178
|
+
errorMessage?: string;
|
|
179
|
+
/** Detailed error information (only present on failure) */
|
|
180
|
+
errorDetails?: {
|
|
181
|
+
message?: string;
|
|
182
|
+
status?: number;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Current position with optional Polymarket metadata enrichment
|
|
187
|
+
*/
|
|
188
|
+
type EnrichedPosition = {
|
|
189
|
+
/** Network identifier (e.g., "ethereum:1", "solana") */
|
|
190
|
+
network: string;
|
|
191
|
+
/** Asset contract address */
|
|
192
|
+
assetAddress: string;
|
|
193
|
+
/** Token ID for NFTs/ERC1155 (null for fungible tokens) */
|
|
194
|
+
tokenId: string | null;
|
|
195
|
+
/** Average unit cost in USD */
|
|
196
|
+
avgUnitCost: string;
|
|
197
|
+
/** Current quantity held (raw amount) */
|
|
198
|
+
currentQty: string;
|
|
199
|
+
/** Optional Polymarket metadata (only present for ERC1155 positions) */
|
|
200
|
+
polymarketMetadata?: {
|
|
201
|
+
/** ERC1155 contract address for the market */
|
|
202
|
+
contractAddress: string;
|
|
203
|
+
/** Token ID for the specific outcome */
|
|
204
|
+
tokenId: string | null;
|
|
205
|
+
/** Token decimals (typically 6) */
|
|
206
|
+
decimals: number;
|
|
207
|
+
/** Unique condition identifier */
|
|
208
|
+
conditionId: string;
|
|
209
|
+
/** Human-readable share count */
|
|
210
|
+
formattedShares: string;
|
|
211
|
+
/** Raw share count in smallest unit */
|
|
212
|
+
shares: string;
|
|
213
|
+
/** Current position value in USD */
|
|
214
|
+
valueUsd: string;
|
|
215
|
+
/** Market question text */
|
|
216
|
+
question: string;
|
|
217
|
+
/** Outcome name (e.g., "Yes", "No") */
|
|
218
|
+
outcome: string;
|
|
219
|
+
/** Current price per share in USD */
|
|
220
|
+
priceUsd: string;
|
|
221
|
+
/** Average purchase price per share in USD */
|
|
222
|
+
averagePriceUsd: string;
|
|
223
|
+
/** Whether position can be redeemed */
|
|
224
|
+
isRedeemable: boolean;
|
|
225
|
+
/** Whether position uses negative risk collateral */
|
|
226
|
+
isNegativeRisk: boolean;
|
|
227
|
+
/** Market image URL */
|
|
228
|
+
imageUrl: string;
|
|
229
|
+
/** Initial position value in USD */
|
|
230
|
+
initialValue: string;
|
|
231
|
+
/** Unrealized profit/loss in USD */
|
|
232
|
+
pnlUsd: string;
|
|
233
|
+
/** Unrealized profit/loss percentage */
|
|
234
|
+
pnlPercent: string;
|
|
235
|
+
/** Realized profit/loss in USD */
|
|
236
|
+
pnlRealizedUsd: string;
|
|
237
|
+
/** Realized profit/loss percentage */
|
|
238
|
+
pnlRealizedPercent: string;
|
|
239
|
+
/** Market end date (ISO 8601 string) */
|
|
240
|
+
endDate: string;
|
|
241
|
+
};
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Data returned from getCurrentPositions() method
|
|
245
|
+
*/
|
|
246
|
+
type CurrentPositionsData = {
|
|
247
|
+
/** Array of current positions with optional Polymarket metadata */
|
|
248
|
+
positions: EnrichedPosition[];
|
|
249
|
+
/** Whether there are pending transactions that may affect position balances */
|
|
250
|
+
hasPendingTxs: boolean;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Response from getCurrentPositions() method
|
|
254
|
+
*
|
|
255
|
+
* Returns the current live positions for the session with optional Polymarket
|
|
256
|
+
* metadata enrichment for ERC1155 positions.
|
|
257
|
+
*/
|
|
258
|
+
type CurrentPositionsResponse = {
|
|
259
|
+
/** Whether the operation was successful */
|
|
260
|
+
success: boolean;
|
|
261
|
+
/** Current positions data (only present on success) */
|
|
262
|
+
data?: CurrentPositionsData;
|
|
263
|
+
/** Error message (only present on failure) */
|
|
264
|
+
error?: string;
|
|
265
|
+
/** Detailed error message (only present on failure) */
|
|
266
|
+
errorMessage?: string;
|
|
267
|
+
/** Detailed error information (only present on failure) */
|
|
268
|
+
errorDetails?: {
|
|
269
|
+
message?: string;
|
|
270
|
+
status?: number;
|
|
271
|
+
};
|
|
272
|
+
};
|
|
142
273
|
|
|
143
274
|
/**
|
|
144
275
|
* Agent log type definitions for agent communication
|
|
@@ -182,6 +313,8 @@ interface SDKConfig {
|
|
|
182
313
|
sessionId: number;
|
|
183
314
|
/** Optional base URL (auto-detected if omitted - internal use only) */
|
|
184
315
|
baseUrl?: string;
|
|
316
|
+
/** Optional Authorization header from incoming request */
|
|
317
|
+
authorizationHeader?: string;
|
|
185
318
|
}
|
|
186
319
|
|
|
187
320
|
/**
|
|
@@ -477,6 +610,7 @@ declare const SwidgeExecuteResponseWrapperSchema: z.ZodObject<{
|
|
|
477
610
|
txs: z.ZodArray<z.ZodString>;
|
|
478
611
|
}, z.core.$strip>;
|
|
479
612
|
lastUpdated: z.ZodNumber;
|
|
613
|
+
error: z.ZodOptional<z.ZodString>;
|
|
480
614
|
}, z.core.$strip>>;
|
|
481
615
|
error: z.ZodOptional<z.ZodString>;
|
|
482
616
|
errorMessage: z.ZodOptional<z.ZodString>;
|
|
@@ -866,7 +1000,6 @@ declare class AgentSdk {
|
|
|
866
1000
|
* fromToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // USDC on Polygon
|
|
867
1001
|
* toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
|
|
868
1002
|
* slippage: "2.0", // 2% slippage for cross-chain (default: 0.5%)
|
|
869
|
-
* priceImpact: "1.0" // 1% max price impact (default: 0.5%)
|
|
870
1003
|
* });
|
|
871
1004
|
*
|
|
872
1005
|
* // 🔄 Swap USDC → ETH on same chain (using defaults)
|
|
@@ -876,7 +1009,6 @@ declare class AgentSdk {
|
|
|
876
1009
|
* amount: "100000000", // $100 USDC (6 decimals)
|
|
877
1010
|
* fromToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC
|
|
878
1011
|
* // toToken omitted = native ETH (default behavior)
|
|
879
|
-
* // slippage defaults to "0.5", priceImpact defaults to "0.5"
|
|
880
1012
|
* });
|
|
881
1013
|
*
|
|
882
1014
|
* if (quote.success && quote.data) {
|
|
@@ -896,6 +1028,10 @@ declare class AgentSdk {
|
|
|
896
1028
|
* `sdk.swidge.quote()` and let the magic happen. Signs transactions, broadcasts them,
|
|
897
1029
|
* and waits for completion.
|
|
898
1030
|
*
|
|
1031
|
+
* Supports both single and bulk execution:
|
|
1032
|
+
* - Pass a single quote → get a single response
|
|
1033
|
+
* - Pass an array of quotes → get an array of responses
|
|
1034
|
+
*
|
|
899
1035
|
* ⚠️ **What happens:**
|
|
900
1036
|
* - Signs transactions using your wallet's policy engine
|
|
901
1037
|
* - Broadcasts to the blockchain(s)
|
|
@@ -904,8 +1040,8 @@ declare class AgentSdk {
|
|
|
904
1040
|
*
|
|
905
1041
|
* 💡 **Pro tip**: The backend handles all the complexity - you just pass the quote!
|
|
906
1042
|
*
|
|
907
|
-
* @param quote Complete quote object from `sdk.swidge.quote()` (the entire `data` field from the quote response)
|
|
908
|
-
* @returns SwidgeExecuteResponse with transaction status and details
|
|
1043
|
+
* @param quote Complete quote object(s) from `sdk.swidge.quote()` (the entire `data` field from the quote response)
|
|
1044
|
+
* @returns SwidgeExecuteResponse or array of responses (matching input type) with transaction status and details
|
|
909
1045
|
* - `success` (boolean): Whether the execution was successful
|
|
910
1046
|
* - `data` (SwidgeExecuteData | undefined): Execution result containing:
|
|
911
1047
|
* - `status`: "success" | "failure" | "refund" | "delayed" - Final transaction status
|
|
@@ -924,10 +1060,9 @@ declare class AgentSdk {
|
|
|
924
1060
|
* amount: "50000000", // $50 USDC
|
|
925
1061
|
* fromToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
|
|
926
1062
|
* toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
927
|
-
* slippage: "2.0", // priceImpact defaults to "0.5"
|
|
928
1063
|
* });
|
|
929
1064
|
*
|
|
930
|
-
* // 2️⃣ Execute the swap
|
|
1065
|
+
* // 2️⃣ Execute the swap (single)
|
|
931
1066
|
* if (quote.success && quote.data) {
|
|
932
1067
|
* const result = await sdk.swidge.execute(quote.data);
|
|
933
1068
|
*
|
|
@@ -949,9 +1084,18 @@ declare class AgentSdk {
|
|
|
949
1084
|
* console.log(`❌ Execute failed: ${result.error}`);
|
|
950
1085
|
* }
|
|
951
1086
|
* }
|
|
1087
|
+
*
|
|
1088
|
+
* // 3️⃣ Bulk execution (multiple quotes)
|
|
1089
|
+
* const results = await sdk.swidge.execute([quote.data, quote.data]);
|
|
1090
|
+
* results.forEach((result, index) => {
|
|
1091
|
+
* console.log(`Swap ${index + 1}: ${result.success ? result.data?.status : result.error}`);
|
|
1092
|
+
* });
|
|
952
1093
|
* ```
|
|
953
1094
|
*/
|
|
954
|
-
execute:
|
|
1095
|
+
execute: {
|
|
1096
|
+
(executeQuote: SwidgeExecuteRequest): Promise<SwidgeExecuteResponse>;
|
|
1097
|
+
(executeQuotes: SwidgeExecuteRequest[]): Promise<SwidgeExecuteResponse[]>;
|
|
1098
|
+
};
|
|
955
1099
|
};
|
|
956
1100
|
/**
|
|
957
1101
|
* 💾 Memory: Session-scoped key-value storage
|
|
@@ -1314,7 +1458,7 @@ declare class AgentSdk {
|
|
|
1314
1458
|
*/
|
|
1315
1459
|
private handleSwidgeQuote;
|
|
1316
1460
|
/**
|
|
1317
|
-
* Handle swidge execute requests
|
|
1461
|
+
* Handle swidge execute requests (single or bulk)
|
|
1318
1462
|
*/
|
|
1319
1463
|
private handleSwidgeExecute;
|
|
1320
1464
|
private handlePolymarketMarketOrder;
|
|
@@ -1335,6 +1479,146 @@ declare class AgentSdk {
|
|
|
1335
1479
|
* Handle memory list requests
|
|
1336
1480
|
*/
|
|
1337
1481
|
private handleMemoryList;
|
|
1482
|
+
/**
|
|
1483
|
+
* 📊 Get transaction ledger with asset changes
|
|
1484
|
+
*
|
|
1485
|
+
* Retrieves all confirmed transaction asset changes for the current session.
|
|
1486
|
+
* Returns both EVM and Solana transactions with their asset transfers.
|
|
1487
|
+
*
|
|
1488
|
+
* **Returns**: `TransactionsResponse`
|
|
1489
|
+
* - `success` (boolean): Whether the operation succeeded
|
|
1490
|
+
* - `data` (AssetChange[] | undefined): Array of asset changes on success
|
|
1491
|
+
* - Each `AssetChange` contains:
|
|
1492
|
+
* - `network` (string): Network identifier (e.g., "ethereum:1", "solana")
|
|
1493
|
+
* - `transactionHash` (string): Transaction hash
|
|
1494
|
+
* - `from` (string): Sender address
|
|
1495
|
+
* - `to` (string): Recipient address
|
|
1496
|
+
* - `amount` (string): Amount transferred (as string to preserve precision)
|
|
1497
|
+
* - `token` (string | null): Token contract address (null for native tokens)
|
|
1498
|
+
* - `tokenId` (string | null): Token ID for NFTs (null for fungible tokens)
|
|
1499
|
+
* - `tokenType` (string): Token type (e.g., "native", "ERC20", "ERC721")
|
|
1500
|
+
* - `tokenUsdPrice` (string | null): Token price in USD at time of transaction
|
|
1501
|
+
* - `timestamp` (string): Transaction timestamp
|
|
1502
|
+
* - `error` (string | undefined): Error message on failure
|
|
1503
|
+
* - `errorMessage` (string | undefined): Detailed error message on failure
|
|
1504
|
+
*
|
|
1505
|
+
* @returns Promise resolving to TransactionsResponse with array of asset changes
|
|
1506
|
+
*
|
|
1507
|
+
* @example
|
|
1508
|
+
* ```ts
|
|
1509
|
+
* const result = await sdk.transactions();
|
|
1510
|
+
*
|
|
1511
|
+
* if (result.success && result.data) {
|
|
1512
|
+
* console.log(`Found ${result.data.length} asset changes`);
|
|
1513
|
+
* result.data.forEach(change => {
|
|
1514
|
+
* console.log(`${change.from} → ${change.to}: ${change.amount} (${change.tokenType})`);
|
|
1515
|
+
* console.log(`Token: ${change.token || 'native'}, USD Price: ${change.tokenUsdPrice || 'N/A'}`);
|
|
1516
|
+
* });
|
|
1517
|
+
* }
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
transactions(): Promise<TransactionsResponse>;
|
|
1521
|
+
/**
|
|
1522
|
+
* 💼 Get current live positions for the session
|
|
1523
|
+
*
|
|
1524
|
+
* Retrieves all current positions held by the session wallet with live balance data.
|
|
1525
|
+
* For ERC1155 positions (e.g., Polymarket), optionally enriches the response with
|
|
1526
|
+
* detailed market metadata including PNL, current prices, and redeemability status.
|
|
1527
|
+
*
|
|
1528
|
+
* **Key Features**:
|
|
1529
|
+
* - Live balance data from the analytics service
|
|
1530
|
+
* - Automatic Polymarket metadata enrichment for ERC1155 positions
|
|
1531
|
+
* - Pending transaction detection to warn of potentially stale balances
|
|
1532
|
+
*
|
|
1533
|
+
* **Returns**: `CurrentPositionsResponse`
|
|
1534
|
+
* - `success` (boolean): Whether the operation succeeded
|
|
1535
|
+
* - `data` (CurrentPositionsData | undefined): Current positions data on success
|
|
1536
|
+
* - `positions` (EnrichedPosition[]): Array of current positions
|
|
1537
|
+
* - `network` (string): Network identifier (e.g., "ethereum:137")
|
|
1538
|
+
* - `assetAddress` (string): Token/asset contract address
|
|
1539
|
+
* - `tokenId` (string | null): Token ID for NFTs/ERC1155 (null for fungible)
|
|
1540
|
+
* - `avgUnitCost` (string): Average unit cost in USD
|
|
1541
|
+
* - `currentQty` (string): Current quantity held (raw amount)
|
|
1542
|
+
* - `polymarketMetadata` (optional): Detailed Polymarket position data
|
|
1543
|
+
* - `question` (string): Market question text
|
|
1544
|
+
* - `outcome` (string): Outcome name (e.g., "Yes", "No")
|
|
1545
|
+
* - `formattedShares` (string): Human-readable share count
|
|
1546
|
+
* - `valueUsd` (string): Current position value in USD
|
|
1547
|
+
* - `priceUsd` (string): Current price per share
|
|
1548
|
+
* - `averagePriceUsd` (string): Average purchase price
|
|
1549
|
+
* - `pnlUsd` (string): Unrealized profit/loss in USD
|
|
1550
|
+
* - `pnlPercent` (string): Unrealized profit/loss percentage
|
|
1551
|
+
* - `isRedeemable` (boolean): Whether position can be redeemed
|
|
1552
|
+
* - `endDate` (string): Market end date
|
|
1553
|
+
* - Plus additional market details
|
|
1554
|
+
* - `hasPendingTxs` (boolean): Whether there are pending transactions
|
|
1555
|
+
* - `error` (string | undefined): Error message on failure
|
|
1556
|
+
* - `errorMessage` (string | undefined): Detailed error message on failure
|
|
1557
|
+
*
|
|
1558
|
+
* @returns Promise resolving to CurrentPositionsResponse with enriched positions
|
|
1559
|
+
*
|
|
1560
|
+
* @example
|
|
1561
|
+
* ```ts
|
|
1562
|
+
* const result = await sdk.getCurrentPositions();
|
|
1563
|
+
*
|
|
1564
|
+
* if (result.success && result.data) {
|
|
1565
|
+
* console.log(`Found ${result.data.positions.length} positions`);
|
|
1566
|
+
*
|
|
1567
|
+
* if (result.data.hasPendingTxs) {
|
|
1568
|
+
* console.log('⚠️ Warning: Pending transactions may affect balances');
|
|
1569
|
+
* }
|
|
1570
|
+
*
|
|
1571
|
+
* result.data.positions.forEach(position => {
|
|
1572
|
+
* console.log(`${position.assetAddress}: ${position.currentQty} units`);
|
|
1573
|
+
* console.log(` Average cost: $${position.avgUnitCost}`);
|
|
1574
|
+
*
|
|
1575
|
+
* // Check for Polymarket enrichment
|
|
1576
|
+
* if (position.polymarketMetadata) {
|
|
1577
|
+
* const pm = position.polymarketMetadata;
|
|
1578
|
+
* console.log(` 📈 ${pm.question}`);
|
|
1579
|
+
* console.log(` Outcome: ${pm.outcome}`);
|
|
1580
|
+
* console.log(` Shares: ${pm.formattedShares}`);
|
|
1581
|
+
* console.log(` Value: $${pm.valueUsd}`);
|
|
1582
|
+
* console.log(` PNL: $${pm.pnlUsd} (${pm.pnlPercent}%)`);
|
|
1583
|
+
* console.log(` Redeemable: ${pm.isRedeemable ? 'Yes' : 'No'}`);
|
|
1584
|
+
* }
|
|
1585
|
+
* });
|
|
1586
|
+
* } else {
|
|
1587
|
+
* console.error(`Failed to get positions: ${result.error}`);
|
|
1588
|
+
* }
|
|
1589
|
+
* ```
|
|
1590
|
+
*
|
|
1591
|
+
* **Success Response Example**:
|
|
1592
|
+
* ```json
|
|
1593
|
+
* {
|
|
1594
|
+
* "success": true,
|
|
1595
|
+
* "data": {
|
|
1596
|
+
* "positions": [
|
|
1597
|
+
* {
|
|
1598
|
+
* "network": "ethereum:137",
|
|
1599
|
+
* "assetAddress": "0x4d97dcd97eC945f40cF65F87097ACe5EA0476045",
|
|
1600
|
+
* "tokenId": "123456",
|
|
1601
|
+
* "avgUnitCost": "0.52",
|
|
1602
|
+
* "currentQty": "10.5",
|
|
1603
|
+
* "polymarketMetadata": {
|
|
1604
|
+
* "question": "Will event X happen?",
|
|
1605
|
+
* "outcome": "Yes",
|
|
1606
|
+
* "formattedShares": "10.5",
|
|
1607
|
+
* "valueUsd": "5.46",
|
|
1608
|
+
* "priceUsd": "0.52",
|
|
1609
|
+
* "averagePriceUsd": "0.50",
|
|
1610
|
+
* "pnlUsd": "0.21",
|
|
1611
|
+
* "pnlPercent": "4.00",
|
|
1612
|
+
* "isRedeemable": false
|
|
1613
|
+
* }
|
|
1614
|
+
* }
|
|
1615
|
+
* ],
|
|
1616
|
+
* "hasPendingTxs": false
|
|
1617
|
+
* }
|
|
1618
|
+
* }
|
|
1619
|
+
* ```
|
|
1620
|
+
*/
|
|
1621
|
+
getCurrentPositions(): Promise<CurrentPositionsResponse>;
|
|
1338
1622
|
}
|
|
1339
1623
|
|
|
1340
1624
|
/**
|
|
@@ -1352,6 +1636,7 @@ declare class AgentSdk {
|
|
|
1352
1636
|
declare class APIClient {
|
|
1353
1637
|
private config;
|
|
1354
1638
|
private baseUrl;
|
|
1639
|
+
private authorizationHeader?;
|
|
1355
1640
|
private isCloudflareWorker;
|
|
1356
1641
|
private hasServiceBinding;
|
|
1357
1642
|
/**
|
|
@@ -1512,6 +1797,7 @@ declare class AgentContext {
|
|
|
1512
1797
|
* @param config.sessionWalletAddress - Wallet address for this session
|
|
1513
1798
|
* @param config.currentPositions - Current positions allocated to this agent
|
|
1514
1799
|
* @param config.baseUrl - Override API base URL (detected automatically otherwise)
|
|
1800
|
+
* @param config.authorizationHeader - Optional Authorization header from incoming request
|
|
1515
1801
|
*
|
|
1516
1802
|
* @example
|
|
1517
1803
|
* ```typescript
|
|
@@ -1529,6 +1815,7 @@ declare class AgentContext {
|
|
|
1529
1815
|
sessionWalletAddress: string;
|
|
1530
1816
|
currentPositions: CurrentPosition[];
|
|
1531
1817
|
baseUrl?: string;
|
|
1818
|
+
authorizationHeader?: string;
|
|
1532
1819
|
});
|
|
1533
1820
|
/**
|
|
1534
1821
|
* Unified logging method that handles console output and backend messaging.
|
|
@@ -1937,7 +2224,6 @@ declare class AgentContext {
|
|
|
1937
2224
|
* - `fromToken` (optional): Source token address (omit for native tokens)
|
|
1938
2225
|
* - `toToken` (optional): Destination token address (omit for native tokens)
|
|
1939
2226
|
* - `slippage` (optional): Slippage tolerance % as string (default: "0.5")
|
|
1940
|
-
* - `priceImpact` (optional): Max price impact % as string (default: "0.5")
|
|
1941
2227
|
*
|
|
1942
2228
|
* **Output**: `SwidgeQuoteResponse`
|
|
1943
2229
|
* - `success`: Whether the quote was retrieved successfully
|
|
@@ -1967,18 +2253,23 @@ declare class AgentContext {
|
|
|
1967
2253
|
*
|
|
1968
2254
|
* Takes your quote and signs/broadcasts transactions automatically.
|
|
1969
2255
|
*
|
|
1970
|
-
*
|
|
2256
|
+
* Supports both single and bulk execution:
|
|
2257
|
+
* - Pass a single quote → get a single response
|
|
2258
|
+
* - Pass an array of quotes → get an array of responses
|
|
2259
|
+
*
|
|
2260
|
+
* **Input**: `SwidgeQuoteData | SwidgeQuoteData[]` - Complete quote object(s) from agent.swidge.quote()
|
|
1971
2261
|
*
|
|
1972
|
-
* **Output**: `SwidgeExecuteResponse`
|
|
2262
|
+
* **Output**: `SwidgeExecuteResponse | SwidgeExecuteResponse[]` (matching input type)
|
|
1973
2263
|
* - `success`: Whether the execution was successful
|
|
1974
2264
|
* - `data`: Execution result with status ("success", "failure", "refund", "delayed") and transaction hashes
|
|
1975
2265
|
* - `error`: Error message if execution failed
|
|
1976
2266
|
*
|
|
1977
|
-
* @param quoteData - Complete quote object from agent.swidge.quote()
|
|
2267
|
+
* @param quoteData - Complete quote object(s) from agent.swidge.quote()
|
|
1978
2268
|
* @returns Promise resolving to SwidgeExecuteResponse with transaction status
|
|
1979
2269
|
*
|
|
1980
2270
|
* @example
|
|
1981
2271
|
* ```typescript
|
|
2272
|
+
* // Single execution
|
|
1982
2273
|
* const quote = await agent.swidge.quote({...});
|
|
1983
2274
|
* if (quote.success && quote.data) {
|
|
1984
2275
|
* const result = await agent.swidge.execute(quote.data);
|
|
@@ -1989,10 +2280,140 @@ declare class AgentContext {
|
|
|
1989
2280
|
* }
|
|
1990
2281
|
* }
|
|
1991
2282
|
* }
|
|
2283
|
+
*
|
|
2284
|
+
* // Bulk execution
|
|
2285
|
+
* const results = await agent.swidge.execute([quote.data, quote2.data]);
|
|
2286
|
+
* results.forEach((result, index) => {
|
|
2287
|
+
* if (result.success && result.data) {
|
|
2288
|
+
* console.log(`Swap ${index + 1} status: ${result.data.status}`);
|
|
2289
|
+
* }
|
|
2290
|
+
* });
|
|
1992
2291
|
* ```
|
|
1993
2292
|
*/
|
|
1994
|
-
execute:
|
|
2293
|
+
execute: {
|
|
2294
|
+
(quoteData: SwidgeQuoteData): Promise<SwidgeExecuteResponse>;
|
|
2295
|
+
(quoteData: SwidgeQuoteData[]): Promise<SwidgeExecuteResponse[]>;
|
|
2296
|
+
};
|
|
1995
2297
|
};
|
|
2298
|
+
/**
|
|
2299
|
+
* Get transaction ledger with asset changes.
|
|
2300
|
+
*
|
|
2301
|
+
* Fetches all confirmed transaction asset changes for this session, including
|
|
2302
|
+
* both EVM and Solana transactions.
|
|
2303
|
+
*
|
|
2304
|
+
* **Output**: `TransactionsResponse`
|
|
2305
|
+
* - `success` (boolean): Whether the operation succeeded
|
|
2306
|
+
* - `data` (AssetChange[] | undefined): Array of asset changes on success
|
|
2307
|
+
* - Each `AssetChange` contains:
|
|
2308
|
+
* - `network` (string): Network identifier (e.g., "ethereum:1", "solana")
|
|
2309
|
+
* - `transactionHash` (string): Transaction hash
|
|
2310
|
+
* - `from` (string): Sender address
|
|
2311
|
+
* - `to` (string): Recipient address
|
|
2312
|
+
* - `amount` (string): Amount transferred (as string to preserve precision)
|
|
2313
|
+
* - `token` (string | null): Token contract address (null for native tokens)
|
|
2314
|
+
* - `tokenId` (string | null): Token ID for NFTs (null for fungible tokens)
|
|
2315
|
+
* - `tokenType` (string): Token type (e.g., "native", "ERC20", "ERC721")
|
|
2316
|
+
* - `tokenUsdPrice` (string | null): Token price in USD at time of transaction
|
|
2317
|
+
* - `timestamp` (string): Transaction timestamp
|
|
2318
|
+
* - `error` (string | undefined): Error message on failure
|
|
2319
|
+
* - `errorMessage` (string | undefined): Detailed error message on failure
|
|
2320
|
+
*
|
|
2321
|
+
* @returns Promise resolving to TransactionsResponse with asset changes
|
|
2322
|
+
*
|
|
2323
|
+
* @example
|
|
2324
|
+
* ```typescript
|
|
2325
|
+
* const result = await agent.transactions();
|
|
2326
|
+
*
|
|
2327
|
+
* if (result.success && result.data) {
|
|
2328
|
+
* await agent.log(`Found ${result.data.length} transactions`);
|
|
2329
|
+
*
|
|
2330
|
+
* // Filter for outgoing transfers
|
|
2331
|
+
* const outgoing = result.data.filter(
|
|
2332
|
+
* change => change.from === agent.sessionWalletAddress
|
|
2333
|
+
* );
|
|
2334
|
+
*
|
|
2335
|
+
* // Calculate total USD value
|
|
2336
|
+
* const totalUsd = result.data
|
|
2337
|
+
* .filter(c => c.tokenUsdPrice)
|
|
2338
|
+
* .reduce((sum, c) => sum + parseFloat(c.amount) * parseFloat(c.tokenUsdPrice!), 0);
|
|
2339
|
+
*
|
|
2340
|
+
* await agent.log(`Total USD value: $${totalUsd.toFixed(2)}`);
|
|
2341
|
+
* } else {
|
|
2342
|
+
* await agent.log(result.error || 'Failed to fetch transactions', { error: true });
|
|
2343
|
+
* }
|
|
2344
|
+
* ```
|
|
2345
|
+
*/
|
|
2346
|
+
transactions(): Promise<TransactionsResponse>;
|
|
2347
|
+
/**
|
|
2348
|
+
* Get current live positions for the session.
|
|
2349
|
+
*
|
|
2350
|
+
* Retrieves all current positions held by the session wallet with live balance data.
|
|
2351
|
+
* For ERC1155 positions (e.g., Polymarket), automatically enriches the response with
|
|
2352
|
+
* detailed market metadata including PNL, current prices, and redeemability status.
|
|
2353
|
+
*
|
|
2354
|
+
* **Output**: `CurrentPositionsResponse`
|
|
2355
|
+
* - `success` (boolean): Whether the operation succeeded
|
|
2356
|
+
* - `data` (CurrentPositionsData | undefined): Current positions data on success
|
|
2357
|
+
* - `hasPendingTxs` (boolean): Whether there are pending transactions
|
|
2358
|
+
* - `positions` (EnrichedPosition[]): Array of current positions
|
|
2359
|
+
* - `network` (string): Network identifier (e.g., "ethereum:137")
|
|
2360
|
+
* - `assetAddress` (string): Token/asset contract address
|
|
2361
|
+
* - `tokenId` (string | null): Token ID for NFTs/ERC1155 (null for fungible)
|
|
2362
|
+
* - `avgUnitCost` (string): Average unit cost in USD
|
|
2363
|
+
* - `currentQty` (string): Current quantity held (raw amount)
|
|
2364
|
+
* - `polymarketMetadata` (optional): Detailed Polymarket position data
|
|
2365
|
+
* - `question` (string): Market question text
|
|
2366
|
+
* - `outcome` (string): Outcome name (e.g., "Yes", "No")
|
|
2367
|
+
* - `formattedShares` (string): Human-readable share count
|
|
2368
|
+
* - `valueUsd` (string): Current position value in USD
|
|
2369
|
+
* - `priceUsd` (string): Current price per share
|
|
2370
|
+
* - `averagePriceUsd` (string): Average purchase price
|
|
2371
|
+
* - `pnlUsd` (string): Unrealized profit/loss in USD
|
|
2372
|
+
* - `pnlPercent` (string): Unrealized profit/loss percentage
|
|
2373
|
+
* - `isRedeemable` (boolean): Whether position can be redeemed
|
|
2374
|
+
* - `endDate` (string): Market end date
|
|
2375
|
+
* - Plus additional market details
|
|
2376
|
+
* - `error` (string | undefined): Error message on failure
|
|
2377
|
+
* - `errorMessage` (string | undefined): Detailed error message on failure
|
|
2378
|
+
*
|
|
2379
|
+
* @returns Promise resolving to CurrentPositionsResponse with enriched positions
|
|
2380
|
+
*
|
|
2381
|
+
* @example
|
|
2382
|
+
* ```typescript
|
|
2383
|
+
* const result = await agent.getCurrentPositions();
|
|
2384
|
+
*
|
|
2385
|
+
* if (result.success && result.data) {
|
|
2386
|
+
* await agent.log(`Managing ${result.data.positions.length} positions`);
|
|
2387
|
+
*
|
|
2388
|
+
* if (result.data.hasPendingTxs) {
|
|
2389
|
+
* await agent.log('⚠️ Warning: Pending transactions may affect balances');
|
|
2390
|
+
* }
|
|
2391
|
+
*
|
|
2392
|
+
* // Iterate through positions
|
|
2393
|
+
* for (const position of result.data.positions) {
|
|
2394
|
+
* await agent.log(`Position: ${position.assetAddress}`);
|
|
2395
|
+
* await agent.log(` Quantity: ${position.currentQty}`);
|
|
2396
|
+
* await agent.log(` Avg Cost: $${position.avgUnitCost}`);
|
|
2397
|
+
*
|
|
2398
|
+
* // Check for Polymarket enrichment
|
|
2399
|
+
* if (position.polymarketMetadata) {
|
|
2400
|
+
* const pm = position.polymarketMetadata;
|
|
2401
|
+
* await agent.log(` Market: ${pm.question}`);
|
|
2402
|
+
* await agent.log(` Outcome: ${pm.outcome}`);
|
|
2403
|
+
* await agent.log(` Value: $${pm.valueUsd}`);
|
|
2404
|
+
* await agent.log(` PNL: $${pm.pnlUsd} (${pm.pnlPercent}%)`);
|
|
2405
|
+
*
|
|
2406
|
+
* if (pm.isRedeemable) {
|
|
2407
|
+
* await agent.log(' ✅ This position is redeemable!');
|
|
2408
|
+
* }
|
|
2409
|
+
* }
|
|
2410
|
+
* }
|
|
2411
|
+
* } else {
|
|
2412
|
+
* await agent.log(result.error || 'Failed to fetch positions', { error: true });
|
|
2413
|
+
* }
|
|
2414
|
+
* ```
|
|
2415
|
+
*/
|
|
2416
|
+
getCurrentPositions(): Promise<CurrentPositionsResponse>;
|
|
1996
2417
|
}
|
|
1997
2418
|
|
|
1998
2419
|
/**
|
|
@@ -2063,7 +2484,8 @@ interface AgentConfig {
|
|
|
2063
2484
|
* HTTP server wrapper for agent functions.
|
|
2064
2485
|
*
|
|
2065
2486
|
* Exposes the following endpoints:
|
|
2066
|
-
* - `POST /
|
|
2487
|
+
* - `POST /run` — required, calls your execution function
|
|
2488
|
+
* - `POST /execute` — backward compatibility, maps to run function
|
|
2067
2489
|
* - `POST /stop` — always available, uses provided or default stop function
|
|
2068
2490
|
* - `GET /health` — always available, uses default health check
|
|
2069
2491
|
*/
|
|
@@ -2106,9 +2528,9 @@ declare class Agent {
|
|
|
2106
2528
|
private updateJobStatus;
|
|
2107
2529
|
private setupRoutes;
|
|
2108
2530
|
private getPortFromPackageJson;
|
|
2109
|
-
run(port?: number): {
|
|
2531
|
+
run(port?: number): Promise<{
|
|
2110
2532
|
fetch: (request: Request, env: any, ctx: any) => Promise<Response>;
|
|
2111
|
-
} | undefined
|
|
2533
|
+
} | undefined>;
|
|
2112
2534
|
/** Get the worker export for Cloudflare Workers environments. */
|
|
2113
2535
|
getExport(): {
|
|
2114
2536
|
fetch: (request: Request, env: any, ctx: any) => Promise<Response>;
|
|
@@ -2138,4 +2560,4 @@ declare function isSolanaNetwork(network: Network): network is "solana";
|
|
|
2138
2560
|
*/
|
|
2139
2561
|
declare function getChainIdFromNetwork(network: `ethereum:${number}`): number;
|
|
2140
2562
|
|
|
2141
|
-
export { APIClient, Agent, AgentContext, AgentSdk, type CurrentPosition, type LogResponse, type MemoryDeleteResponse, type MemoryGetResponse, type MemoryListResponse, type MemorySetResponse, type Network, type PolymarketMarketOrderRequest, type PolymarketMarketOrderResponse, 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, type runFunctionContract };
|
|
2563
|
+
export { APIClient, Agent, AgentContext, AgentSdk, type AssetChange, type CurrentPosition, type CurrentPositionsData, type CurrentPositionsResponse, type EnrichedPosition, type LogResponse, type MemoryDeleteResponse, type MemoryGetResponse, type MemoryListResponse, type MemorySetResponse, type Network, type PolymarketMarketOrderRequest, type PolymarketMarketOrderResponse, 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, type TransactionsResponse, getChainIdFromNetwork, isEthereumNetwork, isSolanaNetwork, type runFunctionContract };
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var __getOwnPropNames=Object.getOwnPropertyNames,__require=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,t)=>("undefined"!=typeof require?require:e)[t]}):e)(function(e){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),__commonJS=(e,t)=>function(){return t||(0,e[__getOwnPropNames(e)[0]])((t={exports:{}}).exports,t),t.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(e){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 e=!1;return this.isCloudflareWorker()&&(void 0!==globalThis.AGENTS_TO_API_PROXY||void 0!==globalThis.__AGENT_ENV__&&globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)&&(e=!0),e}constructor(e){this.config=e,this.baseUrl=e.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 e={};e["X-Session-Id"]=this.config.sessionId.toString();const t=this.getAgentSlug();if(t&&(e["X-Agent-Slug"]=t),!this.hasServiceBinding())try{const t=this.loadAuthConfig();t?.sessionToken&&(e.Authorization=`Bearer ${t.sessionToken}`)}catch(e){}return e}loadAuthConfig(){try{const{loadAuthFromFileSystem:e}=require_auth_loader();return e()}catch(e){}}async makeRequest(e,t={}){const r={...{"Content-Type":"application/json",...this.getAuthHeaders()},...t.headers};let s;if(this.hasServiceBinding()){let o;if(void 0!==globalThis.AGENTS_TO_API_PROXY)o=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");o=globalThis.__AGENT_ENV__.AGENTS_TO_API_PROXY}const a={...t,headers:r},n=`https://agents-to-api-proxy.circuit-0bc.workers.dev${e}`;s=await o.fetch(n,a)}else{const o=`${this.baseUrl}${e}`,a={...t,headers:r};s=await fetch(o,a)}if(!s.ok){const e=await s.json().catch(()=>({})),t=e.message||e.error||`HTTP ${s.status}: ${s.statusText}`,r=new Error(t);throw r.error=e.error,r.errorMessage=e.message,r.errorDetails=e,r.statusCode=s.status,r}return await s.json()}async get(e){return this.makeRequest(e,{method:"GET"})}async post(e,t){return this.makeRequest(e,{method:"POST",body:t?JSON.stringify(t):void 0})}async delete(e){return this.makeRequest(e,{method:"DELETE"})}};function isEthereumNetwork(e){return e.startsWith("ethereum:")}function isSolanaNetwork(e){return"solana"===e}function getChainIdFromNetwork(e){return Number(e.split(":")[1])}var AgentSdk=class{client;config;constructor(e){this.config=e,this.client=new APIClient(e)}async _sendLog(e){await this.client.post("/v1/logs",e)}async signAndSend(e){try{if(isEthereumNetwork(e.network)){const t=getChainIdFromNetwork(e.network);if("toAddress"in e.request)return await this.handleEvmTransaction({chainId:t,toAddress:e.request.toAddress,data:e.request.data,valueWei:e.request.value,message:e.message})}if(isSolanaNetwork(e.network)&&"hexTransaction"in e.request)return await this.handleSolanaTransaction({hexTransaction:e.request.hexTransaction,message:e.message});const t=`Unsupported network: ${e.network}`;return{success:!1,error:"Unsupported Network",errorMessage:t,errorDetails:{message:t}}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{};return t||r?{success:!1,error:t,errorMessage:r,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async signMessage(e){try{if(isEthereumNetwork(e.network))return await this.handleEvmSignMessage(e);const t=`Unsupported network: ${e.network}`;return{success:!1,error:"Unsupported Network",errorMessage:t,errorDetails:{message:t}}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{};return t||r?{success:!1,error:t,errorMessage:r,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}swidge={quote:async e=>this.handleSwidgeQuote(e),execute:async e=>this.handleSwidgeExecute(e)};memory={set:async(e,t)=>this.handleMemorySet(e,t),get:async e=>this.handleMemoryGet(e),delete:async e=>this.handleMemoryDelete(e),list:async()=>this.handleMemoryList()};platforms={polymarket:{marketOrder:async e=>this.handlePolymarketMarketOrder(e),redeemPositions:async e=>this.handlePolymarketRedeemPositions(e||{tokenIds:[]})}};async handleEvmTransaction(e){try{const t=await this.client.post("/v1/transactions/evm",e),r=await this.client.post(`/v1/transactions/evm/${t.internalTransactionId}/broadcast`);return{success:!0,data:{internalTransactionId:t.internalTransactionId,txHash:r.txHash,transactionUrl:r.transactionUrl}}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{};return t||r?{success:!1,error:t,errorMessage:r,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async handleSolanaTransaction(e){try{const t=await this.client.post("/v1/transactions/solana",e),r=await this.client.post(`/v1/transactions/solana/${t.internalTransactionId}/broadcast`);return{success:!0,data:{internalTransactionId:t.internalTransactionId,txHash:r.txHash,transactionUrl:r.transactionUrl}}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{};return t||r?{success:!1,error:t,errorMessage:r,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async handleEvmSignMessage(e){try{return{success:!0,data:await this.client.post("/v1/messages/evm",{messageType:e.request.messageType,data:e.request.data,chainId:e.request.chainId})}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{};return t||r?{success:!1,error:t,errorMessage:r,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async _updateJobStatus(e){try{return await this.client.post(`/v1/jobs/${e.jobId}/status`,e)}catch(e){return{status:400,message:`Failed to update job status: ${e instanceof Error?e.message:"Unknown error"}`}}}async handleSwidgeQuote(e){try{return{success:!0,data:await this.client.post("/v1/swidge/quote",e)}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to get swidge quote";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handleSwidgeExecute(e){try{return{success:!0,data:await this.client.post("/v1/swidge/execute",e)}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to execute swidge swap";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handlePolymarketMarketOrder(e){try{return{success:!0,data:await this.client.post("/v1/platforms/polymarket/market-order",e)}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to execute polymarket market order";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handlePolymarketRedeemPositions(e){try{return{success:!0,data:await this.client.post("/v1/platforms/polymarket/redeem-positions",e)}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to redeem polymarket positions";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handleMemorySet(e,t){try{return{success:!0,data:await this.client.post(`/v1/memory/${e}`,{value:t})}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to set memory";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handleMemoryGet(e){try{return{success:!0,data:await this.client.get(`/v1/memory/${e}`)}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to get memory";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handleMemoryDelete(e){try{return{success:!0,data:await this.client.delete(`/v1/memory/${e}`)}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to delete memory";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}async handleMemoryList(){try{return{success:!0,data:await this.client.get("/v1/memory/list")}}catch(e){const t=e.error,r=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to list memory keys";return{success:!1,error:t||"SDK Error",errorMessage:r||o,errorDetails:s}}}};import{zValidator}from"@hono/zod-validator";import{Hono}from"hono";import{cors}from"hono/cors";import{z}from"zod";var AgentContext=class{sessionId;sessionWalletAddress;currentPositions;t;constructor(e){this.sessionId=e.sessionId,this.sessionWalletAddress=e.sessionWalletAddress,this.currentPositions=e.currentPositions,this.t=new AgentSdk({sessionId:e.sessionId,baseUrl:e.baseUrl})}async log(e,t){const{error:r=!1,debug:s=!1}=t||{};let o,a;const n=(e,t)=>{if("bigint"==typeof t)return t.toString();if("function"==typeof t)return`[Function: ${t.name||"anonymous"}]`;if(void 0===t)return"[undefined]";if(null===t)return null;if("object"==typeof t&&!Array.isArray(t)&&t.toString!==Object.prototype.toString)try{const e=t.toString();if("[object Object]"!==e)return e}catch(e){}return t};if("object"==typeof e&&null!==e?(o=JSON.stringify(e,n,2),a=JSON.stringify(e,n)):(o=String(e),a=String(e)),r?console.log(`[ERROR] ${o}`):console.log(o),s)return{success:!0};const i=r?"error":"observe";try{const e=a.length>250?a.slice(0,250):a;return await this.t._sendLog([{type:i,shortMessage:e}]),{success:!0}}catch(e){const t=e instanceof Error?e.message:"Failed to send log";return console.error(`Failed to send log to backend: ${t}`),{success:!1,error:"Log Error",errorMessage:t,errorDetails:{message:t,type:e instanceof Error?e.constructor.name:"UnknownError"}}}}async signAndSend(e){return this.t.signAndSend(e)}async signMessage(e){return this.t.signMessage(e)}memory={set:async(e,t)=>this.t.memory.set(e,t),get:async e=>this.t.memory.get(e),delete:async e=>this.t.memory.delete(e),list:async()=>this.t.memory.list()};platforms={polymarket:{marketOrder:async e=>this.t.platforms.polymarket.marketOrder(e),redeemPositions:async e=>this.t.platforms.polymarket.redeemPositions(e)}};swidge={quote:async e=>this.t.swidge.quote(e),execute:async e=>this.t.swidge.execute(e)}},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)}),HealthResponseSchema=z.object({status:z.string()}),Agent=class{app;runFunction;stopFunction;healthCheckFunction=async()=>({status:"healthy",timestamp:(new Date).toISOString()});constructor(e){this.app=new Hono,this.runFunction=e.runFunction,this.stopFunction=e.stopFunction,this.app.use("*",cors()),this.setupRoutes()}defaultStopFunction=async e=>{await e.log(`Agent stopped for session ${e.sessionId}`)};async executeWithJobTracking(e,t){let r,s=!1;try{const r=new AgentContext({sessionId:e.sessionId,sessionWalletAddress:e.sessionWalletAddress,currentPositions:e.currentPositions});await t(r),s=!0}catch(e){r=this.getErrorMessage(e),s=!1,console.error("Agent function error:",r)}finally{e.jobId&&await this.updateJobStatus(e.sessionId,e.jobId,s?"success":"failed",r)}}getErrorMessage(e){if(null==e)return"Unknown error";try{const t=e?.constructor?.name||"Error";let r="";r=e instanceof Error&&e.message||String(e),r=r.replace(/[^\x20-\x7E\n\t]/g,"");const s=`${t}: ${r}`;return s.length>1e3?`${s.substring(0,997)}...`:s}catch{return"Unknown error (message extraction failed)"}}async updateJobStatus(e,t,r,s){const o=new AgentSdk({sessionId:e});for(let e=1;e<=3;e++)try{return await o._updateJobStatus({jobId:t,status:r,errorMessage:s}),void console.log(`Job status updated to '${r}' (attempt ${e})`)}catch(t){console.error(`Status update attempt ${e}/3 failed:`,t),e<3&&await new Promise(t=>setTimeout(t,100*2**(e-1)))}if("failed"===r)try{return await o._updateJobStatus({jobId:t,status:r,errorMessage:void 0}),void console.warn(`Job status updated to '${r}' without error message`)}catch(e){console.error(`CRITICAL: Failed to update job ${t} status. Likely API connectivity issue:`,e)}else console.error(`CRITICAL: Failed to update job ${t} status to success after 3 attempts`)}setupRoutes(){this.app.post("/execute",zValidator("json",AgentRequestSchema),async e=>{const t=e.req.valid("json");return await this.executeWithJobTracking(t,this.runFunction),e.json({success:!0,message:"Execution completed"})}),this.app.post("/stop",zValidator("json",AgentRequestSchema),async e=>{const t=e.req.valid("json"),r=this.stopFunction||this.defaultStopFunction;return await this.executeWithJobTracking(t,r),e.json({success:!0,message:"Stop completed"})}),this.app.get("/health",async e=>{try{const t=await this.healthCheckFunction();return e.json(t)}catch(t){return console.error("Agent health check error:",t),e.json({status:"unhealthy",error:t instanceof Error?t.message:"Unknown error",timestamp:(new Date).toISOString()},500)}})}getPortFromPackageJson(){try{const e=__require("fs"),t=__require("path").join(process.cwd(),"package.json");if(e.existsSync(t)){const r=JSON.parse(e.readFileSync(t,"utf-8"));if(r.circuit?.port)return console.log("⚠️ Warning: circuit.port in package.json is deprecated. Use AGENT_PORT environment variable instead."),Number.parseInt(r.circuit.port,10)}}catch(e){console.log("Could not read package.json for port configuration")}return null}run(port){const isCloudflareWorker="undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare;if(isCloudflareWorker)return this.getExport();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),console.log("🔧 Agent configuration:"),console.log(` Explicit port parameter: ${port||"not set"}`),console.log(` process.env.AGENT_PORT: ${process.env.AGENT_PORT||"not set"}`),console.log(` Bun.env.AGENT_PORT: ${bunEnv?.AGENT_PORT||"not set"}`),console.log(` package.json circuit.port: ${packageJsonPort||"not set"} (deprecated)`),console.log(` Final port: ${finalPort}`);try{const req=eval("require"),{serve:serve}=req("@hono/node-server");console.log(`🚀 Server is running on port ${finalPort}`),serve({fetch:this.app.fetch,port:finalPort})}catch(e){console.error("Failed to start local server. @hono/node-server is not available."),console.error("For local development, install @hono/node-server: npm install @hono/node-server"),process.exit(1)}}getExport(){return{fetch:async(e,t,r)=>(t&&"undefined"!=typeof globalThis&&(globalThis.__AGENT_ENV__=t),this.app.fetch(e,t,r))}}};function createAgentHandler(e,t){return new Agent({runFunction:e,stopFunction:t})}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(),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().nullish(),maxFeePerGas:z2.number().nullish(),maxPriorityFeePerGas:z2.number().nullish()}),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=e=>z2.object({success:z2.boolean(),data:e.optional(),error:z2.string().optional(),errorMessage:z2.string().optional(),errorDetails:z2.object({message:z2.string().optional(),error:z2.string().optional(),status:z2.number().optional(),statusText:z2.string().optional()}).optional()}),SwidgeQuoteResponseWrapperSchema=SwidgeSDKResponseSchema(SwidgeQuoteDataSchema),SwidgeExecuteResponseWrapperSchema=SwidgeSDKResponseSchema(SwidgeExecuteResponseSchema);export{APIClient,Agent,AgentContext,AgentSdk,QUOTE_RESULT,getChainIdFromNetwork,isEthereumNetwork,isSolanaNetwork};
|
|
1
|
+
import{loadAuthFromFileSystem as e}from"./chunk-4I3A6QAK.js";var r=class{config;baseUrl;authorizationHeader;isCloudflareWorker(){return"undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare}hasServiceBinding(){if(this.isCloudflareWorker()){if(void 0!==globalThis.AGENTS_TO_API_PROXY)return!0;if(void 0!==globalThis.__AGENT_ENV__&&globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)return!0}return!1}constructor(e){this.config=e,this.baseUrl=e.baseUrl||"https://agents.circuit.org",this.authorizationHeader=e.authorizationHeader}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 e={};e["X-Session-Id"]=this.config.sessionId.toString();const r=this.getAgentSlug();if(r&&(e["X-Agent-Slug"]=r),this.isCloudflareWorker())return e;if(this.authorizationHeader)return e.Authorization=this.authorizationHeader,e;try{const r=this.loadAuthConfig();r?.sessionToken&&(e.Authorization=`Bearer ${r.sessionToken}`)}catch{}return e}loadAuthConfig(){try{return e()}catch{}}async makeRequest(e,r={}){const t={...{"Content-Type":"application/json",...this.getAuthHeaders()},...r.headers};let s;if(this.hasServiceBinding()){let o;if(void 0!==globalThis.AGENTS_TO_API_PROXY)o=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");o=globalThis.__AGENT_ENV__.AGENTS_TO_API_PROXY}const a={...r,headers:t},n=`https://agents-to-api-proxy.circuit-0bc.workers.dev${e}`;s=await o.fetch(n,a)}else{const o=`${this.baseUrl}${e}`,a={...r,headers:t};s=await fetch(o,a)}if(!s.ok){const e=await s.json().catch(()=>({})),r=e.message||e.error||`HTTP ${s.status}: ${s.statusText}`,t=new Error(r);throw t.error=e.error,t.errorMessage=e.message,t.errorDetails=e,t.statusCode=s.status,t}return await s.json()}async get(e){return this.makeRequest(e,{method:"GET"})}async post(e,r){return this.makeRequest(e,{method:"POST",body:r?JSON.stringify(r):void 0})}async delete(e){return this.makeRequest(e,{method:"DELETE"})}};function t(e){return e.startsWith("ethereum:")}function s(e){return"solana"===e}function o(e){return Number(e.split(":")[1])}var a=class{client;config;constructor(e){this.config=e,this.client=new r(e)}async _sendLog(e){await this.client.post("/v1/logs",e)}async signAndSend(e){try{if(t(e.network)){const r=o(e.network);if("toAddress"in e.request)return await this.handleEvmTransaction({chainId:r,toAddress:e.request.toAddress,data:e.request.data,valueWei:e.request.value,message:e.message})}if(s(e.network)&&"hexTransaction"in e.request)return await this.handleSolanaTransaction({hexTransaction:e.request.hexTransaction,message:e.message});const r=`Unsupported network: ${e.network}`;return{success:!1,error:"Unsupported Network",errorMessage:r,errorDetails:{message:r}}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{};return r||t?{success:!1,error:r,errorMessage:t,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async signMessage(e){try{if(t(e.network))return await this.handleEvmSignMessage(e);const r=`Unsupported network: ${e.network}`;return{success:!1,error:"Unsupported Network",errorMessage:r,errorDetails:{message:r}}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{};return r||t?{success:!1,error:r,errorMessage:t,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}swidge={quote:async e=>this.handleSwidgeQuote(e),execute:function(e){return this.handleSwidgeExecute(e)}.bind(this)};memory={set:async(e,r)=>this.handleMemorySet(e,r),get:async e=>this.handleMemoryGet(e),delete:async e=>this.handleMemoryDelete(e),list:async()=>this.handleMemoryList()};platforms={polymarket:{marketOrder:async e=>this.handlePolymarketMarketOrder(e),redeemPositions:async e=>this.handlePolymarketRedeemPositions(e||{tokenIds:[]})}};async handleEvmTransaction(e){try{const r=await this.client.post("/v1/transactions/evm",e),t=await this.client.post(`/v1/transactions/evm/${r.internalTransactionId}/broadcast`);return{success:!0,data:{internalTransactionId:r.internalTransactionId,txHash:t.txHash,transactionUrl:t.transactionUrl}}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{};return r||t?{success:!1,error:r,errorMessage:t,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async handleSolanaTransaction(e){try{const r=await this.client.post("/v1/transactions/solana",e),t=await this.client.post(`/v1/transactions/solana/${r.internalTransactionId}/broadcast`);return{success:!0,data:{internalTransactionId:r.internalTransactionId,txHash:t.txHash,transactionUrl:t.transactionUrl}}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{};return r||t?{success:!1,error:r,errorMessage:t,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async handleEvmSignMessage(e){try{return{success:!0,data:await this.client.post("/v1/messages/evm",{messageType:e.request.messageType,data:e.request.data,chainId:e.request.chainId})}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{};return r||t?{success:!1,error:r,errorMessage:t,errorDetails:s}:{success:!1,error:"SDK Error",errorMessage:e instanceof Error?e.message:"Unknown error",errorDetails:{}}}}async _updateJobStatus(e){try{return await this.client.post(`/v1/jobs/${e.jobId}/status`,e)}catch(e){return{status:400,message:`Failed to update job status: ${e instanceof Error?e.message:"Unknown error"}`}}}async handleSwidgeQuote(e){try{return{success:!0,data:await this.client.post("/v1/swidge/quote",e)}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to get swidge quote";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async handleSwidgeExecute(e){try{const r=await this.client.post("/v1/swidge/execute",e);if(Array.isArray(r))return r.map(e=>{const r="success"===e.status;return{success:r,data:e,error:r?void 0:e.error}});const t="success"===r.status;return{success:t,data:r,error:t?void 0:r.error}}catch(r){const t=r.error,s=r.errorMessage,o=r.errorDetails||{},a=r instanceof Error?r.message:"Failed to execute swidge swap";return Array.isArray(e)?[{success:!1,error:t||"SDK Error",errorMessage:s||a,errorDetails:o}]:{success:!1,error:t||"SDK Error",errorMessage:s||a,errorDetails:o}}}async handlePolymarketMarketOrder(e){try{return{success:!0,data:await this.client.post("/v1/platforms/polymarket/market-order",e)}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to execute polymarket market order";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async handlePolymarketRedeemPositions(e){try{return{success:!0,data:await this.client.post("/v1/platforms/polymarket/redeem-positions",e)}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to redeem polymarket positions";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async handleMemorySet(e,r){try{return{success:!0,data:await this.client.post(`/v1/memory/${e}`,{value:r})}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to set memory";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async handleMemoryGet(e){try{return{success:!0,data:await this.client.get(`/v1/memory/${e}`)}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to get memory";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async handleMemoryDelete(e){try{return{success:!0,data:await this.client.delete(`/v1/memory/${e}`)}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to delete memory";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async handleMemoryList(){try{return{success:!0,data:await this.client.get("/v1/memory/list")}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to list memory keys";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async transactions(){try{return{success:!0,data:await this.client.get("/v1/transactions/ledger")}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to fetch transactions";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}async getCurrentPositions(){try{return{success:!0,data:await this.client.get("/v1/positions/current")}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to fetch current positions";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}};import{existsSync as n,readFileSync as i}from"fs";import{join as c}from"path";import{zValidator as u}from"@hono/zod-validator";import{Hono as l}from"hono";import{cors as d}from"hono/cors";import*as h from"zod";var m=class{sessionId;sessionWalletAddress;currentPositions;t;constructor(e){this.sessionId=e.sessionId,this.sessionWalletAddress=e.sessionWalletAddress,this.currentPositions=e.currentPositions,this.t=new a({sessionId:e.sessionId,baseUrl:e.baseUrl,authorizationHeader:e.authorizationHeader})}async log(e,r){const{error:t=!1,debug:s=!1}=r||{};let o,a;const n=(e,r)=>{if("bigint"==typeof r)return r.toString();if("function"==typeof r)return`[Function: ${r.name||"anonymous"}]`;if(void 0===r)return"[undefined]";if(null===r)return null;if("object"==typeof r&&!Array.isArray(r)&&r.toString!==Object.prototype.toString)try{const e=r.toString();if("[object Object]"!==e)return e}catch(e){}return r};if("object"==typeof e&&null!==e?(o=JSON.stringify(e,n,2),a=JSON.stringify(e,n)):(o=String(e),a=String(e)),t?console.error(o):console.log(o),s)return{success:!0};const i=t?"error":"observe";try{const e=a.length>250?a.slice(0,250):a;return await this.t._sendLog([{type:i,shortMessage:e}]),{success:!0}}catch(e){const r=e instanceof Error?e.message:"Failed to send log";return console.error(`Failed to send log to backend: ${r}`),{success:!1,error:"Log Error",errorMessage:r,errorDetails:{message:r,type:e instanceof Error?e.constructor.name:"UnknownError"}}}}async signAndSend(e){return this.t.signAndSend(e)}async signMessage(e){return this.t.signMessage(e)}memory={set:async(e,r)=>this.t.memory.set(e,r),get:async e=>this.t.memory.get(e),delete:async e=>this.t.memory.delete(e),list:async()=>this.t.memory.list()};platforms={polymarket:{marketOrder:async e=>this.t.platforms.polymarket.marketOrder(e),redeemPositions:async e=>this.t.platforms.polymarket.redeemPositions(e)}};swidge={quote:async e=>this.t.swidge.quote(e),execute:function(e){return this.t.swidge.execute(e)}.bind(this)};async transactions(){return this.t.transactions()}async getCurrentPositions(){return this.t.getCurrentPositions()}},g=h.object({network:h.string(),assetAddress:h.string(),tokenId:h.string().nullable(),avgUnitCost:h.string(),currentQty:h.string()}),y=h.object({sessionId:h.number(),sessionWalletAddress:h.string(),jobId:h.string().optional(),currentPositions:h.array(g)}),p=(h.object({status:h.string()}),class{app;runFunction;stopFunction;healthCheckFunction=async()=>({status:"healthy",timestamp:(new Date).toISOString()});constructor(e){this.app=new l,this.runFunction=e.runFunction,this.stopFunction=e.stopFunction,this.app.use("*",d()),this.setupRoutes()}defaultStopFunction=async e=>{await e.log(`Agent stopped for session ${e.sessionId}`)};async executeWithJobTracking(e,r,t){let s,o=!1;try{const s=new m({sessionId:e.sessionId,sessionWalletAddress:e.sessionWalletAddress,currentPositions:e.currentPositions,authorizationHeader:t});await r(s),o=!0}catch(e){s=this.getErrorMessage(e),o=!1,console.error("Agent function error:",s)}finally{e.jobId&&await this.updateJobStatus(e.sessionId,e.jobId,o?"success":"failed",s,t)}}getErrorMessage(e){if(null==e)return"Unknown error";try{const r=e?.constructor?.name||"Error";let t="";t=e instanceof Error&&e.message||String(e),t=t.replace(/[^\x20-\x7E\n\t]/g,"");const s=`${r}: ${t}`;return s.length>1e3?`${s.substring(0,997)}...`:s}catch{return"Unknown error (message extraction failed)"}}async updateJobStatus(e,r,t,s,o){const n=new a({sessionId:e,authorizationHeader:o});for(let e=1;e<=3;e++)try{return void await n._updateJobStatus({jobId:r,status:t,errorMessage:s})}catch(r){console.error(`Status update attempt ${e}/3 failed:`,r),e<3&&await new Promise(r=>setTimeout(r,100*2**(e-1)))}if("failed"===t)try{return console.warn(`Issue updating job status to '${t}' with error message, attempting to update status without error message`),void await n._updateJobStatus({jobId:r,status:t,errorMessage:void 0})}catch(e){console.error(`CRITICAL: Failed to update job ${r} status. Likely API connectivity issue:`,e)}else console.error(`CRITICAL: Failed to update job ${r} status to success after 3 attempts`)}setupRoutes(){this.app.post("/run",u("json",y),async e=>{const r=e.req.valid("json"),t=e.req.header("Authorization");return await this.executeWithJobTracking(r,this.runFunction,t),e.json({success:!0,message:"Execution completed"})}),this.app.post("/execute",u("json",y),async e=>{const r=e.req.valid("json"),t=e.req.header("Authorization");return await this.executeWithJobTracking(r,this.runFunction,t),e.json({success:!0,message:"Execution completed"})}),this.app.post("/stop",u("json",y),async e=>{const r=e.req.valid("json"),t=e.req.header("Authorization"),s=this.stopFunction||this.defaultStopFunction;return await this.executeWithJobTracking(r,s,t),e.json({success:!0,message:"Stop completed"})}),this.app.get("/health",async e=>{try{const r=await this.healthCheckFunction();return e.json(r)}catch(r){return console.error("Agent health check error:",r),e.json({status:"unhealthy",error:r instanceof Error?r.message:"Unknown error",timestamp:(new Date).toISOString()},500)}})}getPortFromPackageJson(){try{const e=c(process.cwd(),"package.json");if(n(e)){const r=JSON.parse(i(e,"utf-8"));if(r.circuit?.port)return console.log("⚠️ Warning: circuit.port in package.json is deprecated. Use AGENT_PORT environment variable instead."),Number.parseInt(r.circuit.port,10)}}catch(e){console.log("Could not read package.json for port configuration")}return null}async run(e){if("undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare)return this.getExport();const r=globalThis.Bun?.env,t=process.env.AGENT_PORT||r?.AGENT_PORT,s=this.getPortFromPackageJson();let o=e;!o&&t&&(o=Number.parseInt(t,10)),!o&&s&&(o=s),o||(o=3e3),console.log("🔧 Agent configuration:"),console.log(` Explicit port parameter: ${e||"not set"}`),console.log(` process.env.AGENT_PORT: ${process.env.AGENT_PORT||"not set"}`),console.log(` Bun.env.AGENT_PORT: ${r?.AGENT_PORT||"not set"}`),console.log(` package.json circuit.port: ${s||"not set"} (deprecated)`),console.log(` Final port: ${o}`);try{const{serve:e}=await import("@hono/node-server");console.log(`🚀 Server is running on port ${o}`),console.log("📍 Available endpoints: GET /health, POST /run, POST /execute (backward compat), POST /stop"),e({fetch:this.app.fetch,port:o})}catch(e){console.error("Failed to start local server. @hono/node-server is not available."),console.error("For local development, install @hono/node-server: npm install @hono/node-server"),process.exit(1)}}getExport(){return{fetch:async(e,r,t)=>(r&&"undefined"!=typeof globalThis&&(globalThis.__AGENT_ENV__=r),this.app.fetch(e,r,t))}}});import{z as f}from"zod";var w=f.templateLiteral(["ethereum:",f.coerce.number().int().nonnegative()]),v=f.union([f.literal("solana"),w]),E=f.object({address:f.string(),network:v}),T=(f.object({from:E,to:E,fromToken:f.string().optional(),toToken:f.string().optional(),amount:f.string(),slippage:f.string().optional()}),f.object({network:v,address:f.string(),token:f.string().nullable(),name:f.string().optional(),symbol:f.string().optional(),decimals:f.number().optional(),amount:f.string().optional(),minimumAmount:f.string().optional(),amountFormatted:f.string().optional(),amountUsd:f.string().optional()})),b=f.object({usd:f.string().optional(),percentage:f.string().optional()}),k=f.object({name:f.string(),amount:f.string().optional(),amountFormatted:f.string().optional(),amountUsd:f.string().optional()}),D=f.object({programId:f.string(),keys:f.array(f.object({pubkey:f.string(),isSigner:f.boolean(),isWritable:f.boolean()})),data:f.union([f.string(),f.instanceof(Buffer)])}),S=f.object({type:f.literal("evm"),from:f.string().regex(/^0x[a-fA-F0-9]{40}$/),to:f.string().regex(/^0x[a-fA-F0-9]{40}$/),chainId:f.number(),value:f.number(),data:f.string().regex(/^0x[a-fA-F0-9]*$/),gas:f.number().nullish(),maxFeePerGas:f.number().nullish(),maxPriorityFeePerGas:f.number().nullish()}),A=f.object({type:f.literal("solana"),instructions:f.array(D),addressLookupTableAddresses:f.array(f.string())}),M=f.object({type:f.literal("transaction"),description:f.string(),transactionDetails:f.union([S,A]),metadata:f.record(f.string(),f.string())}),F=f.object({type:f.literal("signature"),description:f.string(),signatureData:f.string(),metadata:f.record(f.string(),f.string())}),$=f.discriminatedUnion("type",[M,F]),O=f.object({engine:f.literal("relay"),assetSend:T,assetReceive:T,priceImpact:b,fees:f.array(k),steps:f.array($)}),U=f.object({network:f.string(),txs:f.array(f.string())}),x=f.object({status:f.union([f.literal("success"),f.literal("failure"),f.literal("refund"),f.literal("delayed")]),in:U,out:U,lastUpdated:f.number(),error:f.string().optional()}),I={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"},P=e=>f.object({success:f.boolean(),data:e.optional(),error:f.string().optional(),errorMessage:f.string().optional(),errorDetails:f.object({message:f.string().optional(),error:f.string().optional(),status:f.number().optional(),statusText:f.string().optional()}).optional()});P(O),P(x);export{r as APIClient,p as Agent,m as AgentContext,a as AgentSdk,I as QUOTE_RESULT,o as getChainIdFromNetwork,t as isEthereumNetwork,s as isSolanaNetwork};
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{loadAuthFromFileSystem as o}from"../chunk-4I3A6QAK.js";export{o as loadAuthFromFileSystem};
|
package/utils/auth-loader.cjs
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
// This file is intentionally in JavaScript to avoid TypeScript/bundler transformations
|
|
2
|
-
// It provides a way to load auth config from the file system in Node.js environments
|
|
3
|
-
|
|
4
|
-
function loadAuthFromFileSystem() {
|
|
5
|
-
try {
|
|
6
|
-
// Check if we're in a Node.js environment
|
|
7
|
-
if (typeof process === 'undefined') {
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// Use dynamic require to avoid bundler processing
|
|
12
|
-
const fs = eval("require")('fs');
|
|
13
|
-
const path = eval("require")('path');
|
|
14
|
-
const os = eval("require")('os');
|
|
15
|
-
|
|
16
|
-
// Use os.homedir() for cross-platform compatibility (works on Windows, Mac, Linux)
|
|
17
|
-
const homeDir = os.homedir();
|
|
18
|
-
|
|
19
|
-
// Try main config directory first (matches CLI behavior)
|
|
20
|
-
let authPath = path.join(homeDir, '.config', 'circuit', 'auth.json');
|
|
21
|
-
|
|
22
|
-
if (!fs.existsSync(authPath)) {
|
|
23
|
-
// Try fallback directory (matches CLI fallback behavior)
|
|
24
|
-
authPath = path.join(homeDir, '.circuit', 'auth.json');
|
|
25
|
-
|
|
26
|
-
if (!fs.existsSync(authPath)) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const authContent = fs.readFileSync(authPath, 'utf-8');
|
|
32
|
-
return JSON.parse(authContent);
|
|
33
|
-
} catch (error) {
|
|
34
|
-
// Silently fail if we can't read the auth config
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
module.exports = { loadAuthFromFileSystem };
|