@circuitorg/agent-sdk 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -224,7 +224,6 @@ async function run(agent: AgentContext): Promise<void> {
224
224
  amount: "1000000000000000", // 0.001 ETH
225
225
  toToken: "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
226
226
  slippage: "2.0",
227
- priceImpact: "100.0"
228
227
  });
229
228
 
230
229
  if (!quote.success) {
@@ -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,49 @@ 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
+ };
142
185
 
143
186
  /**
144
187
  * Agent log type definitions for agent communication
@@ -182,6 +225,8 @@ interface SDKConfig {
182
225
  sessionId: number;
183
226
  /** Optional base URL (auto-detected if omitted - internal use only) */
184
227
  baseUrl?: string;
228
+ /** Optional Authorization header from incoming request */
229
+ authorizationHeader?: string;
185
230
  }
186
231
 
187
232
  /**
@@ -866,7 +911,6 @@ declare class AgentSdk {
866
911
  * fromToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", // USDC on Polygon
867
912
  * toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
868
913
  * slippage: "2.0", // 2% slippage for cross-chain (default: 0.5%)
869
- * priceImpact: "1.0" // 1% max price impact (default: 0.5%)
870
914
  * });
871
915
  *
872
916
  * // 🔄 Swap USDC → ETH on same chain (using defaults)
@@ -876,7 +920,6 @@ declare class AgentSdk {
876
920
  * amount: "100000000", // $100 USDC (6 decimals)
877
921
  * fromToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC
878
922
  * // toToken omitted = native ETH (default behavior)
879
- * // slippage defaults to "0.5", priceImpact defaults to "0.5"
880
923
  * });
881
924
  *
882
925
  * if (quote.success && quote.data) {
@@ -924,7 +967,6 @@ declare class AgentSdk {
924
967
  * amount: "50000000", // $50 USDC
925
968
  * fromToken: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
926
969
  * toToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
927
- * slippage: "2.0", // priceImpact defaults to "0.5"
928
970
  * });
929
971
  *
930
972
  * // 2️⃣ Execute the swap
@@ -1335,6 +1377,45 @@ declare class AgentSdk {
1335
1377
  * Handle memory list requests
1336
1378
  */
1337
1379
  private handleMemoryList;
1380
+ /**
1381
+ * 📊 Get transaction ledger with asset changes
1382
+ *
1383
+ * Retrieves all confirmed transaction asset changes for the current session.
1384
+ * Returns both EVM and Solana transactions with their asset transfers.
1385
+ *
1386
+ * **Returns**: `TransactionsResponse`
1387
+ * - `success` (boolean): Whether the operation succeeded
1388
+ * - `data` (AssetChange[] | undefined): Array of asset changes on success
1389
+ * - Each `AssetChange` contains:
1390
+ * - `network` (string): Network identifier (e.g., "ethereum:1", "solana")
1391
+ * - `transactionHash` (string): Transaction hash
1392
+ * - `from` (string): Sender address
1393
+ * - `to` (string): Recipient address
1394
+ * - `amount` (string): Amount transferred (as string to preserve precision)
1395
+ * - `token` (string | null): Token contract address (null for native tokens)
1396
+ * - `tokenId` (string | null): Token ID for NFTs (null for fungible tokens)
1397
+ * - `tokenType` (string): Token type (e.g., "native", "ERC20", "ERC721")
1398
+ * - `tokenUsdPrice` (string | null): Token price in USD at time of transaction
1399
+ * - `timestamp` (string): Transaction timestamp
1400
+ * - `error` (string | undefined): Error message on failure
1401
+ * - `errorMessage` (string | undefined): Detailed error message on failure
1402
+ *
1403
+ * @returns Promise resolving to TransactionsResponse with array of asset changes
1404
+ *
1405
+ * @example
1406
+ * ```ts
1407
+ * const result = await sdk.transactions();
1408
+ *
1409
+ * if (result.success && result.data) {
1410
+ * console.log(`Found ${result.data.length} asset changes`);
1411
+ * result.data.forEach(change => {
1412
+ * console.log(`${change.from} → ${change.to}: ${change.amount} (${change.tokenType})`);
1413
+ * console.log(`Token: ${change.token || 'native'}, USD Price: ${change.tokenUsdPrice || 'N/A'}`);
1414
+ * });
1415
+ * }
1416
+ * ```
1417
+ */
1418
+ transactions(): Promise<TransactionsResponse>;
1338
1419
  }
1339
1420
 
1340
1421
  /**
@@ -1352,6 +1433,7 @@ declare class AgentSdk {
1352
1433
  declare class APIClient {
1353
1434
  private config;
1354
1435
  private baseUrl;
1436
+ private authorizationHeader?;
1355
1437
  private isCloudflareWorker;
1356
1438
  private hasServiceBinding;
1357
1439
  /**
@@ -1512,6 +1594,7 @@ declare class AgentContext {
1512
1594
  * @param config.sessionWalletAddress - Wallet address for this session
1513
1595
  * @param config.currentPositions - Current positions allocated to this agent
1514
1596
  * @param config.baseUrl - Override API base URL (detected automatically otherwise)
1597
+ * @param config.authorizationHeader - Optional Authorization header from incoming request
1515
1598
  *
1516
1599
  * @example
1517
1600
  * ```typescript
@@ -1529,6 +1612,7 @@ declare class AgentContext {
1529
1612
  sessionWalletAddress: string;
1530
1613
  currentPositions: CurrentPosition[];
1531
1614
  baseUrl?: string;
1615
+ authorizationHeader?: string;
1532
1616
  });
1533
1617
  /**
1534
1618
  * Unified logging method that handles console output and backend messaging.
@@ -1937,7 +2021,6 @@ declare class AgentContext {
1937
2021
  * - `fromToken` (optional): Source token address (omit for native tokens)
1938
2022
  * - `toToken` (optional): Destination token address (omit for native tokens)
1939
2023
  * - `slippage` (optional): Slippage tolerance % as string (default: "0.5")
1940
- * - `priceImpact` (optional): Max price impact % as string (default: "0.5")
1941
2024
  *
1942
2025
  * **Output**: `SwidgeQuoteResponse`
1943
2026
  * - `success`: Whether the quote was retrieved successfully
@@ -1993,6 +2076,55 @@ declare class AgentContext {
1993
2076
  */
1994
2077
  execute: (quoteData: SwidgeQuoteData) => Promise<SwidgeExecuteResponse>;
1995
2078
  };
2079
+ /**
2080
+ * Get transaction ledger with asset changes.
2081
+ *
2082
+ * Fetches all confirmed transaction asset changes for this session, including
2083
+ * both EVM and Solana transactions.
2084
+ *
2085
+ * **Output**: `TransactionsResponse`
2086
+ * - `success` (boolean): Whether the operation succeeded
2087
+ * - `data` (AssetChange[] | undefined): Array of asset changes on success
2088
+ * - Each `AssetChange` contains:
2089
+ * - `network` (string): Network identifier (e.g., "ethereum:1", "solana")
2090
+ * - `transactionHash` (string): Transaction hash
2091
+ * - `from` (string): Sender address
2092
+ * - `to` (string): Recipient address
2093
+ * - `amount` (string): Amount transferred (as string to preserve precision)
2094
+ * - `token` (string | null): Token contract address (null for native tokens)
2095
+ * - `tokenId` (string | null): Token ID for NFTs (null for fungible tokens)
2096
+ * - `tokenType` (string): Token type (e.g., "native", "ERC20", "ERC721")
2097
+ * - `tokenUsdPrice` (string | null): Token price in USD at time of transaction
2098
+ * - `timestamp` (string): Transaction timestamp
2099
+ * - `error` (string | undefined): Error message on failure
2100
+ * - `errorMessage` (string | undefined): Detailed error message on failure
2101
+ *
2102
+ * @returns Promise resolving to TransactionsResponse with asset changes
2103
+ *
2104
+ * @example
2105
+ * ```typescript
2106
+ * const result = await agent.transactions();
2107
+ *
2108
+ * if (result.success && result.data) {
2109
+ * await agent.log(`Found ${result.data.length} transactions`);
2110
+ *
2111
+ * // Filter for outgoing transfers
2112
+ * const outgoing = result.data.filter(
2113
+ * change => change.from === agent.sessionWalletAddress
2114
+ * );
2115
+ *
2116
+ * // Calculate total USD value
2117
+ * const totalUsd = result.data
2118
+ * .filter(c => c.tokenUsdPrice)
2119
+ * .reduce((sum, c) => sum + parseFloat(c.amount) * parseFloat(c.tokenUsdPrice!), 0);
2120
+ *
2121
+ * await agent.log(`Total USD value: $${totalUsd.toFixed(2)}`);
2122
+ * } else {
2123
+ * await agent.log(result.error || 'Failed to fetch transactions', { error: true });
2124
+ * }
2125
+ * ```
2126
+ */
2127
+ transactions(): Promise<TransactionsResponse>;
1996
2128
  }
1997
2129
 
1998
2130
  /**
@@ -2063,7 +2195,8 @@ interface AgentConfig {
2063
2195
  * HTTP server wrapper for agent functions.
2064
2196
  *
2065
2197
  * Exposes the following endpoints:
2066
- * - `POST /execute` — required, calls your execution function
2198
+ * - `POST /run` — required, calls your execution function
2199
+ * - `POST /execute` — backward compatibility, maps to run function
2067
2200
  * - `POST /stop` — always available, uses provided or default stop function
2068
2201
  * - `GET /health` — always available, uses default health check
2069
2202
  */
@@ -2106,9 +2239,9 @@ declare class Agent {
2106
2239
  private updateJobStatus;
2107
2240
  private setupRoutes;
2108
2241
  private getPortFromPackageJson;
2109
- run(port?: number): {
2242
+ run(port?: number): Promise<{
2110
2243
  fetch: (request: Request, env: any, ctx: any) => Promise<Response>;
2111
- } | undefined;
2244
+ } | undefined>;
2112
2245
  /** Get the worker export for Cloudflare Workers environments. */
2113
2246
  getExport(): {
2114
2247
  fetch: (request: Request, env: any, ctx: any) => Promise<Response>;
@@ -2138,4 +2271,4 @@ declare function isSolanaNetwork(network: Network): network is "solana";
2138
2271
  */
2139
2272
  declare function getChainIdFromNetwork(network: `ethereum:${number}`): number;
2140
2273
 
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 };
2274
+ export { APIClient, Agent, AgentContext, AgentSdk, type AssetChange, 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, 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:async e=>this.handleSwidgeExecute(e)};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{return{success:!0,data:await this.client.post("/v1/swidge/execute",e)}}catch(e){const r=e.error,t=e.errorMessage,s=e.errorDetails||{},o=e instanceof Error?e.message:"Failed to execute swidge swap";return{success:!1,error:r||"SDK Error",errorMessage:t||o,errorDetails:s}}}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}}}};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:async e=>this.t.swidge.execute(e)};async transactions(){return this.t.transactions()}},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()}),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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circuitorg/agent-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "typescript sdk for the Agent Toolset Service",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -0,0 +1,6 @@
1
+ interface AuthConfig {
2
+ sessionToken: string;
3
+ }
4
+ declare function loadAuthFromFileSystem(): AuthConfig | undefined;
5
+
6
+ export { loadAuthFromFileSystem };
@@ -0,0 +1 @@
1
+ import{loadAuthFromFileSystem as o}from"../chunk-4I3A6QAK.js";export{o as loadAuthFromFileSystem};
@@ -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 };