@exagent/agent 0.1.46 → 0.1.47

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/dist/cli.js CHANGED
@@ -1552,16 +1552,25 @@ var init_executor = __esm({
1552
1552
  config;
1553
1553
  allowedTokens;
1554
1554
  configHashFn;
1555
- constructor(client, config, configHashFn) {
1555
+ vaultManager;
1556
+ constructor(client, config, configHashFn, vaultManager) {
1556
1557
  this.client = client;
1557
1558
  this.config = config;
1558
1559
  this.configHashFn = configHashFn;
1560
+ this.vaultManager = vaultManager;
1559
1561
  this.allowedTokens = new Set(
1560
1562
  (config.allowedTokens || []).map((t) => t.toLowerCase())
1561
1563
  );
1562
1564
  }
1563
1565
  /**
1564
- * Execute a single trade signal
1566
+ * Set the vault manager (allows wiring after construction)
1567
+ */
1568
+ setVaultManager(vm) {
1569
+ this.vaultManager = vm;
1570
+ }
1571
+ /**
1572
+ * Execute a single trade signal.
1573
+ * Tries vault trading first if vault exists, falls back to wallet trading.
1565
1574
  */
1566
1575
  async execute(signal) {
1567
1576
  if (signal.action === "hold") {
@@ -1574,13 +1583,38 @@ var init_executor = __esm({
1574
1583
  return { success: false, error: "Signal exceeds position limits" };
1575
1584
  }
1576
1585
  const configHash = this.configHashFn?.();
1577
- const result = await this.client.trade({
1586
+ const tradeIntent = {
1578
1587
  tokenIn: signal.tokenIn,
1579
1588
  tokenOut: signal.tokenOut,
1580
1589
  amountIn: signal.amountIn,
1581
1590
  maxSlippageBps: this.config.trading?.maxSlippageBps ?? 100,
1582
1591
  ...configHash && { configHash }
1583
- });
1592
+ };
1593
+ if (this.vaultManager) {
1594
+ const vaultAddress = await this.vaultManager.getVaultAddress();
1595
+ if (vaultAddress && this.vaultManager.preferVaultTrading) {
1596
+ const routerTrade = await this.client.buildRouterTrade(tradeIntent);
1597
+ if (routerTrade.vaultParams) {
1598
+ console.log(`Attempting vault trade via ${vaultAddress}`);
1599
+ const vaultResult = await this.vaultManager.executeVaultTrade({
1600
+ tokenIn: signal.tokenIn,
1601
+ tokenOut: signal.tokenOut,
1602
+ amountIn: BigInt(signal.amountIn),
1603
+ minAmountOut: BigInt(routerTrade.minAmountOut),
1604
+ vaultParams: routerTrade.vaultParams
1605
+ });
1606
+ if (vaultResult) {
1607
+ if (vaultResult.txHash) {
1608
+ console.log(`Vault trade executed: ${vaultResult.txHash}`);
1609
+ return { success: true, txHash: vaultResult.txHash };
1610
+ }
1611
+ console.error(`Vault trade failed: ${vaultResult.error}`);
1612
+ return { success: false, error: vaultResult.error };
1613
+ }
1614
+ }
1615
+ }
1616
+ }
1617
+ const result = await this.client.trade(tradeIntent);
1584
1618
  console.log(`Trade executed: ${result.hash}`);
1585
1619
  return { success: true, txHash: result.hash };
1586
1620
  } catch (error) {
@@ -4388,9 +4422,10 @@ var VAULT_ABI = [
4388
4422
  outputs: [{ type: "uint256" }],
4389
4423
  stateMutability: "view"
4390
4424
  },
4425
+ // TOKEN → base asset (fee from output)
4391
4426
  {
4392
4427
  type: "function",
4393
- name: "executeTrade",
4428
+ name: "executeSwap",
4394
4429
  inputs: [
4395
4430
  { name: "tokenIn", type: "address" },
4396
4431
  { name: "tokenOut", type: "address" },
@@ -4398,6 +4433,44 @@ var VAULT_ABI = [
4398
4433
  { name: "minAmountOut", type: "uint256" },
4399
4434
  { name: "aggregator", type: "address" },
4400
4435
  { name: "swapData", type: "bytes" },
4436
+ { name: "feeConvertAggregator", type: "address" },
4437
+ { name: "feeSwapData", type: "bytes" },
4438
+ { name: "deadline", type: "uint256" }
4439
+ ],
4440
+ outputs: [{ type: "uint256" }],
4441
+ stateMutability: "nonpayable"
4442
+ },
4443
+ // Base asset → TOKEN (fee from input)
4444
+ {
4445
+ type: "function",
4446
+ name: "executeSwapSimple",
4447
+ inputs: [
4448
+ { name: "tokenIn", type: "address" },
4449
+ { name: "tokenOut", type: "address" },
4450
+ { name: "amountIn", type: "uint256" },
4451
+ { name: "minAmountOut", type: "uint256" },
4452
+ { name: "target", type: "address" },
4453
+ { name: "data", type: "bytes" },
4454
+ { name: "feeConvertAggregator", type: "address" },
4455
+ { name: "feeSwapData", type: "bytes" },
4456
+ { name: "deadline", type: "uint256" }
4457
+ ],
4458
+ outputs: [{ type: "uint256" }],
4459
+ stateMutability: "nonpayable"
4460
+ },
4461
+ // TOKEN → TOKEN (multi-hop via USDC, fee at midpoint)
4462
+ {
4463
+ type: "function",
4464
+ name: "executeSwapMultiHop",
4465
+ inputs: [
4466
+ { name: "tokenIn", type: "address" },
4467
+ { name: "tokenOut", type: "address" },
4468
+ { name: "amountIn", type: "uint256" },
4469
+ { name: "minAmountOut", type: "uint256" },
4470
+ { name: "aggregator1", type: "address" },
4471
+ { name: "swapData1", type: "bytes" },
4472
+ { name: "aggregator2", type: "address" },
4473
+ { name: "swapData2", type: "bytes" },
4401
4474
  { name: "deadline", type: "uint256" }
4402
4475
  ],
4403
4476
  outputs: [{ type: "uint256" }],
@@ -4663,8 +4736,9 @@ var VaultManager = class {
4663
4736
  }
4664
4737
  }
4665
4738
  /**
4666
- * Execute a trade through the vault (if it exists and policy allows)
4667
- * Returns null if should use direct trading instead
4739
+ * Execute a trade through the vault using API-provided vaultParams.
4740
+ * Dispatches to the correct vault function based on swapType.
4741
+ * Returns null if vault trading shouldn't be used (no vault, policy disabled).
4668
4742
  */
4669
4743
  async executeVaultTrade(params) {
4670
4744
  if (!this.preferVaultTrading) {
@@ -4675,23 +4749,71 @@ var VaultManager = class {
4675
4749
  return null;
4676
4750
  }
4677
4751
  const deadline = params.deadline || BigInt(Math.floor(Date.now() / 1e3) + 3600);
4752
+ const { vaultParams } = params;
4678
4753
  try {
4679
- const hash = await this.walletClient.writeContract({
4680
- address: vaultAddress,
4681
- abi: VAULT_ABI,
4682
- functionName: "executeTrade",
4683
- args: [
4684
- params.tokenIn,
4685
- params.tokenOut,
4686
- params.amountIn,
4687
- params.minAmountOut,
4688
- params.aggregator,
4689
- params.swapData,
4690
- deadline
4691
- ],
4692
- chain: import_chains2.base,
4693
- account: this.account
4694
- });
4754
+ let hash;
4755
+ switch (vaultParams.swapType) {
4756
+ case "swap":
4757
+ hash = await this.walletClient.writeContract({
4758
+ address: vaultAddress,
4759
+ abi: VAULT_ABI,
4760
+ functionName: "executeSwap",
4761
+ args: [
4762
+ params.tokenIn,
4763
+ params.tokenOut,
4764
+ params.amountIn,
4765
+ params.minAmountOut,
4766
+ vaultParams.aggregator,
4767
+ vaultParams.swapData,
4768
+ vaultParams.feeConvertAggregator,
4769
+ vaultParams.feeSwapData,
4770
+ deadline
4771
+ ],
4772
+ chain: import_chains2.base,
4773
+ account: this.account
4774
+ });
4775
+ break;
4776
+ case "simple":
4777
+ hash = await this.walletClient.writeContract({
4778
+ address: vaultAddress,
4779
+ abi: VAULT_ABI,
4780
+ functionName: "executeSwapSimple",
4781
+ args: [
4782
+ params.tokenIn,
4783
+ params.tokenOut,
4784
+ params.amountIn,
4785
+ params.minAmountOut,
4786
+ vaultParams.target,
4787
+ vaultParams.data,
4788
+ vaultParams.feeConvertAggregator,
4789
+ vaultParams.feeSwapData,
4790
+ deadline
4791
+ ],
4792
+ chain: import_chains2.base,
4793
+ account: this.account
4794
+ });
4795
+ break;
4796
+ case "multihop":
4797
+ hash = await this.walletClient.writeContract({
4798
+ address: vaultAddress,
4799
+ abi: VAULT_ABI,
4800
+ functionName: "executeSwapMultiHop",
4801
+ args: [
4802
+ params.tokenIn,
4803
+ params.tokenOut,
4804
+ params.amountIn,
4805
+ params.minAmountOut,
4806
+ vaultParams.aggregator1,
4807
+ vaultParams.swapData1,
4808
+ vaultParams.aggregator2,
4809
+ vaultParams.swapData2,
4810
+ deadline
4811
+ ],
4812
+ chain: import_chains2.base,
4813
+ account: this.account
4814
+ });
4815
+ break;
4816
+ }
4695
4817
  return { usedVault: true, txHash: hash };
4696
4818
  } catch (error) {
4697
4819
  return {
@@ -7949,7 +8071,7 @@ function loadSecureEnv(basePath, passphrase) {
7949
8071
  }
7950
8072
 
7951
8073
  // src/index.ts
7952
- var AGENT_VERSION = "0.1.46";
8074
+ var AGENT_VERSION = "0.1.47";
7953
8075
 
7954
8076
  // src/relay.ts
7955
8077
  var RelayClient = class {
@@ -8410,10 +8532,16 @@ var AgentRuntime = class {
8410
8532
  vaultConfig
8411
8533
  });
8412
8534
  console.log(`Vault policy: ${vaultConfig.policy}`);
8535
+ if (this.executor) {
8536
+ this.executor.setVaultManager(this.vaultManager);
8537
+ }
8413
8538
  const status = await this.vaultManager.getVaultStatus();
8414
8539
  if (status.hasVault) {
8415
8540
  console.log(`Vault exists: ${status.vaultAddress}`);
8416
8541
  console.log(`Vault TVL: ${Number(status.totalAssets) / 1e6} USDC`);
8542
+ if (vaultConfig.preferVaultTrading) {
8543
+ console.log("Vault trading enabled \u2014 trades will execute from vault");
8544
+ }
8417
8545
  } else {
8418
8546
  console.log("No vault exists for this agent");
8419
8547
  if (vaultConfig.policy === "manual") {
@@ -9834,8 +9962,9 @@ This exit has been recorded in your trade history and counts toward your total P
9834
9962
  this.paperPortfolio.save();
9835
9963
  } else {
9836
9964
  const vaultStatus = await this.vaultManager?.getVaultStatus();
9837
- if (vaultStatus?.hasVault && this.vaultManager?.preferVaultTrading) {
9838
- console.log(`Trading through vault: ${vaultStatus.vaultAddress}`);
9965
+ if (vaultStatus?.hasVault) {
9966
+ const via = this.vaultManager?.preferVaultTrading ? "vault" : "wallet";
9967
+ console.log(`Vault active: ${vaultStatus.vaultAddress} (trades execute from ${via})`);
9839
9968
  }
9840
9969
  const results = await this.executor.executeAll(filteredSignals);
9841
9970
  let totalFeesUSD = 0;
package/dist/cli.mjs CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  results_exports,
30
30
  saveSessionResult,
31
31
  validateConfig
32
- } from "./chunk-7QMPWDX3.mjs";
32
+ } from "./chunk-ICTDJ7VX.mjs";
33
33
 
34
34
  // src/backtest/data-loader.ts
35
35
  import * as fs from "fs";
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { Address, Hash, PublicClient, HttpTransport, WalletClient } from 'viem';
3
- import { ExagentClient } from '@exagent/sdk';
3
+ import { VaultTradeParams, ExagentClient } from '@exagent/sdk';
4
4
  import { base } from 'viem/chains';
5
5
 
6
6
  /** Risk state persisted across restarts */
@@ -967,16 +967,16 @@ declare class VaultManager {
967
967
  error?: string;
968
968
  }>;
969
969
  /**
970
- * Execute a trade through the vault (if it exists and policy allows)
971
- * Returns null if should use direct trading instead
970
+ * Execute a trade through the vault using API-provided vaultParams.
971
+ * Dispatches to the correct vault function based on swapType.
972
+ * Returns null if vault trading shouldn't be used (no vault, policy disabled).
972
973
  */
973
974
  executeVaultTrade(params: {
974
975
  tokenIn: Address;
975
976
  tokenOut: Address;
976
977
  amountIn: bigint;
977
978
  minAmountOut: bigint;
978
- aggregator: Address;
979
- swapData: `0x${string}`;
979
+ vaultParams: VaultTradeParams;
980
980
  deadline?: bigint;
981
981
  }): Promise<{
982
982
  usedVault: boolean;
@@ -1538,17 +1538,23 @@ declare function getAllStrategyTemplates(): StrategyTemplate[];
1538
1538
  /**
1539
1539
  * Trade Executor
1540
1540
  * Handles execution of trade signals through the ExagentRouter.
1541
- * All trades go through the router there is no direct DEX bypass.
1542
- * Pre-checks token eligibility to avoid wasting gas on reverts.
1541
+ * Tries vault trading first (if vault exists and policy allows),
1542
+ * then falls back to wallet trading. All trades route through the router.
1543
1543
  */
1544
1544
  declare class TradeExecutor {
1545
1545
  private client;
1546
1546
  private config;
1547
1547
  private allowedTokens;
1548
1548
  private configHashFn?;
1549
- constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string);
1549
+ private vaultManager?;
1550
+ constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string, vaultManager?: VaultManager);
1550
1551
  /**
1551
- * Execute a single trade signal
1552
+ * Set the vault manager (allows wiring after construction)
1553
+ */
1554
+ setVaultManager(vm: VaultManager): void;
1555
+ /**
1556
+ * Execute a single trade signal.
1557
+ * Tries vault trading first if vault exists, falls back to wallet trading.
1552
1558
  */
1553
1559
  execute(signal: TradeSignal): Promise<{
1554
1560
  success: boolean;
@@ -3353,6 +3359,6 @@ declare function decryptEnvFile(encPath: string, passphrase: string): Record<str
3353
3359
  declare function loadSecureEnv(basePath: string, passphrase?: string): boolean;
3354
3360
 
3355
3361
  /** @exagent/agent package version — update alongside package.json */
3356
- declare const AGENT_VERSION = "0.1.46";
3362
+ declare const AGENT_VERSION = "0.1.47";
3357
3363
 
3358
3364
  export { AGENT_VERSION, type AccountSummary, type AgentConfig, AgentConfigSchema, type AgentMode, AgentRuntime, type AgentStatusPayload, AnthropicAdapter, BaseLLMAdapter, type BridgeResult, type BridgeStep, type CommandType, DeepSeekAdapter, FileStore, type FillCallback, type FundingCallback, type FundingPayment, GoogleAdapter, GroqAdapter, HYPERLIQUID_DOMAIN, HyperliquidClient, HyperliquidSigner, HyperliquidWebSocket, type InferredExit, type LLMAdapter, type LLMConfig, LLMConfigSchema, type LLMMessage, type LLMMetadata, type LLMProvider, LLMProviderSchema, type LLMResponse, type LiquidationCallback, type LocalPosition, MARKET_CATEGORIES, MarketBrowser, type MarketCategory, type MarketData, MarketDataService, type MessageLevel, type MessageType, MistralAdapter, OllamaAdapter, type OnboardingStatus, OpenAIAdapter, OrderManager, type OrderResult, type PerpAction, type PerpConfig$1 as PerpConfig, PerpConfigSchema, type PerpFill, type PerpMarketData, PerpOnboarding, type PerpPosition, type PerpStrategyFunction, PerpTradeRecorder, type PerpTradeSignal, type PerpConfig as PerpTradingConfig, PolymarketClient, PositionManager, type PositionSummary, PositionTracker, type PredictionAccountSummary, type PredictionAction, type PredictionConfig$1 as PredictionConfig, PredictionConfigSchema, type PredictionFill, PredictionFunding, type PredictionFundingConfig, type PredictionMarket, PredictionOrderManager, type PredictionPosition, PredictionPositionManager, type PredictionStrategyFunction, PredictionTradeRecorder, type PredictionTradeSignal, type PredictionConfig as PredictionTradingConfig, type RecordPerpTradeParams, type RecordPredictionTradeParams, RelayClient, type RelayCommand, type RelayConfig$1 as RelayConfig, RelayConfigSchema, RiskManager, type RiskState, type RiskUniverse, RiskUniverseSchema, type RuntimeConfig, STRATEGY_TEMPLATES, type StrategyContext, type StrategyFunction, type StrategyStore, type StrategyTemplate, type StuckPosition, TogetherAdapter, type TrackedPosition, TradeExecutor, type TradeRecord, type TradeSignal, type TradingConfig, TradingConfigSchema, type VaultConfig, VaultConfigSchema, VaultManager, type VaultManagerConfig, type VaultPolicy, VaultPolicySchema, type VaultStatus, calculatePredictionFee, createLLMAdapter, createSampleConfig, decodePredictionInstrument, decryptEnvFile, encodePredictionInstrument, encryptEnvFile, fillHashToBytes32, fillOidToBytes32, getAllStrategyTemplates, getNextNonce, getStrategyTemplate, loadConfig, loadSecureEnv, loadStrategy, orderIdToBytes32, tradeIdToBytes32, validateConfig, validateStrategy };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { Address, Hash, PublicClient, HttpTransport, WalletClient } from 'viem';
3
- import { ExagentClient } from '@exagent/sdk';
3
+ import { VaultTradeParams, ExagentClient } from '@exagent/sdk';
4
4
  import { base } from 'viem/chains';
5
5
 
6
6
  /** Risk state persisted across restarts */
@@ -967,16 +967,16 @@ declare class VaultManager {
967
967
  error?: string;
968
968
  }>;
969
969
  /**
970
- * Execute a trade through the vault (if it exists and policy allows)
971
- * Returns null if should use direct trading instead
970
+ * Execute a trade through the vault using API-provided vaultParams.
971
+ * Dispatches to the correct vault function based on swapType.
972
+ * Returns null if vault trading shouldn't be used (no vault, policy disabled).
972
973
  */
973
974
  executeVaultTrade(params: {
974
975
  tokenIn: Address;
975
976
  tokenOut: Address;
976
977
  amountIn: bigint;
977
978
  minAmountOut: bigint;
978
- aggregator: Address;
979
- swapData: `0x${string}`;
979
+ vaultParams: VaultTradeParams;
980
980
  deadline?: bigint;
981
981
  }): Promise<{
982
982
  usedVault: boolean;
@@ -1538,17 +1538,23 @@ declare function getAllStrategyTemplates(): StrategyTemplate[];
1538
1538
  /**
1539
1539
  * Trade Executor
1540
1540
  * Handles execution of trade signals through the ExagentRouter.
1541
- * All trades go through the router there is no direct DEX bypass.
1542
- * Pre-checks token eligibility to avoid wasting gas on reverts.
1541
+ * Tries vault trading first (if vault exists and policy allows),
1542
+ * then falls back to wallet trading. All trades route through the router.
1543
1543
  */
1544
1544
  declare class TradeExecutor {
1545
1545
  private client;
1546
1546
  private config;
1547
1547
  private allowedTokens;
1548
1548
  private configHashFn?;
1549
- constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string);
1549
+ private vaultManager?;
1550
+ constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string, vaultManager?: VaultManager);
1550
1551
  /**
1551
- * Execute a single trade signal
1552
+ * Set the vault manager (allows wiring after construction)
1553
+ */
1554
+ setVaultManager(vm: VaultManager): void;
1555
+ /**
1556
+ * Execute a single trade signal.
1557
+ * Tries vault trading first if vault exists, falls back to wallet trading.
1552
1558
  */
1553
1559
  execute(signal: TradeSignal): Promise<{
1554
1560
  success: boolean;
@@ -3353,6 +3359,6 @@ declare function decryptEnvFile(encPath: string, passphrase: string): Record<str
3353
3359
  declare function loadSecureEnv(basePath: string, passphrase?: string): boolean;
3354
3360
 
3355
3361
  /** @exagent/agent package version — update alongside package.json */
3356
- declare const AGENT_VERSION = "0.1.46";
3362
+ declare const AGENT_VERSION = "0.1.47";
3357
3363
 
3358
3364
  export { AGENT_VERSION, type AccountSummary, type AgentConfig, AgentConfigSchema, type AgentMode, AgentRuntime, type AgentStatusPayload, AnthropicAdapter, BaseLLMAdapter, type BridgeResult, type BridgeStep, type CommandType, DeepSeekAdapter, FileStore, type FillCallback, type FundingCallback, type FundingPayment, GoogleAdapter, GroqAdapter, HYPERLIQUID_DOMAIN, HyperliquidClient, HyperliquidSigner, HyperliquidWebSocket, type InferredExit, type LLMAdapter, type LLMConfig, LLMConfigSchema, type LLMMessage, type LLMMetadata, type LLMProvider, LLMProviderSchema, type LLMResponse, type LiquidationCallback, type LocalPosition, MARKET_CATEGORIES, MarketBrowser, type MarketCategory, type MarketData, MarketDataService, type MessageLevel, type MessageType, MistralAdapter, OllamaAdapter, type OnboardingStatus, OpenAIAdapter, OrderManager, type OrderResult, type PerpAction, type PerpConfig$1 as PerpConfig, PerpConfigSchema, type PerpFill, type PerpMarketData, PerpOnboarding, type PerpPosition, type PerpStrategyFunction, PerpTradeRecorder, type PerpTradeSignal, type PerpConfig as PerpTradingConfig, PolymarketClient, PositionManager, type PositionSummary, PositionTracker, type PredictionAccountSummary, type PredictionAction, type PredictionConfig$1 as PredictionConfig, PredictionConfigSchema, type PredictionFill, PredictionFunding, type PredictionFundingConfig, type PredictionMarket, PredictionOrderManager, type PredictionPosition, PredictionPositionManager, type PredictionStrategyFunction, PredictionTradeRecorder, type PredictionTradeSignal, type PredictionConfig as PredictionTradingConfig, type RecordPerpTradeParams, type RecordPredictionTradeParams, RelayClient, type RelayCommand, type RelayConfig$1 as RelayConfig, RelayConfigSchema, RiskManager, type RiskState, type RiskUniverse, RiskUniverseSchema, type RuntimeConfig, STRATEGY_TEMPLATES, type StrategyContext, type StrategyFunction, type StrategyStore, type StrategyTemplate, type StuckPosition, TogetherAdapter, type TrackedPosition, TradeExecutor, type TradeRecord, type TradeSignal, type TradingConfig, TradingConfigSchema, type VaultConfig, VaultConfigSchema, VaultManager, type VaultManagerConfig, type VaultPolicy, VaultPolicySchema, type VaultStatus, calculatePredictionFee, createLLMAdapter, createSampleConfig, decodePredictionInstrument, decryptEnvFile, encodePredictionInstrument, encryptEnvFile, fillHashToBytes32, fillOidToBytes32, getAllStrategyTemplates, getNextNonce, getStrategyTemplate, loadConfig, loadSecureEnv, loadStrategy, orderIdToBytes32, tradeIdToBytes32, validateConfig, validateStrategy };
package/dist/index.js CHANGED
@@ -2377,16 +2377,25 @@ var TradeExecutor = class {
2377
2377
  config;
2378
2378
  allowedTokens;
2379
2379
  configHashFn;
2380
- constructor(client, config, configHashFn) {
2380
+ vaultManager;
2381
+ constructor(client, config, configHashFn, vaultManager) {
2381
2382
  this.client = client;
2382
2383
  this.config = config;
2383
2384
  this.configHashFn = configHashFn;
2385
+ this.vaultManager = vaultManager;
2384
2386
  this.allowedTokens = new Set(
2385
2387
  (config.allowedTokens || []).map((t) => t.toLowerCase())
2386
2388
  );
2387
2389
  }
2388
2390
  /**
2389
- * Execute a single trade signal
2391
+ * Set the vault manager (allows wiring after construction)
2392
+ */
2393
+ setVaultManager(vm) {
2394
+ this.vaultManager = vm;
2395
+ }
2396
+ /**
2397
+ * Execute a single trade signal.
2398
+ * Tries vault trading first if vault exists, falls back to wallet trading.
2390
2399
  */
2391
2400
  async execute(signal) {
2392
2401
  if (signal.action === "hold") {
@@ -2399,13 +2408,38 @@ var TradeExecutor = class {
2399
2408
  return { success: false, error: "Signal exceeds position limits" };
2400
2409
  }
2401
2410
  const configHash = this.configHashFn?.();
2402
- const result = await this.client.trade({
2411
+ const tradeIntent = {
2403
2412
  tokenIn: signal.tokenIn,
2404
2413
  tokenOut: signal.tokenOut,
2405
2414
  amountIn: signal.amountIn,
2406
2415
  maxSlippageBps: this.config.trading?.maxSlippageBps ?? 100,
2407
2416
  ...configHash && { configHash }
2408
- });
2417
+ };
2418
+ if (this.vaultManager) {
2419
+ const vaultAddress = await this.vaultManager.getVaultAddress();
2420
+ if (vaultAddress && this.vaultManager.preferVaultTrading) {
2421
+ const routerTrade = await this.client.buildRouterTrade(tradeIntent);
2422
+ if (routerTrade.vaultParams) {
2423
+ console.log(`Attempting vault trade via ${vaultAddress}`);
2424
+ const vaultResult = await this.vaultManager.executeVaultTrade({
2425
+ tokenIn: signal.tokenIn,
2426
+ tokenOut: signal.tokenOut,
2427
+ amountIn: BigInt(signal.amountIn),
2428
+ minAmountOut: BigInt(routerTrade.minAmountOut),
2429
+ vaultParams: routerTrade.vaultParams
2430
+ });
2431
+ if (vaultResult) {
2432
+ if (vaultResult.txHash) {
2433
+ console.log(`Vault trade executed: ${vaultResult.txHash}`);
2434
+ return { success: true, txHash: vaultResult.txHash };
2435
+ }
2436
+ console.error(`Vault trade failed: ${vaultResult.error}`);
2437
+ return { success: false, error: vaultResult.error };
2438
+ }
2439
+ }
2440
+ }
2441
+ }
2442
+ const result = await this.client.trade(tradeIntent);
2409
2443
  console.log(`Trade executed: ${result.hash}`);
2410
2444
  return { success: true, txHash: result.hash };
2411
2445
  } catch (error) {
@@ -2891,9 +2925,10 @@ var VAULT_ABI = [
2891
2925
  outputs: [{ type: "uint256" }],
2892
2926
  stateMutability: "view"
2893
2927
  },
2928
+ // TOKEN → base asset (fee from output)
2894
2929
  {
2895
2930
  type: "function",
2896
- name: "executeTrade",
2931
+ name: "executeSwap",
2897
2932
  inputs: [
2898
2933
  { name: "tokenIn", type: "address" },
2899
2934
  { name: "tokenOut", type: "address" },
@@ -2901,6 +2936,44 @@ var VAULT_ABI = [
2901
2936
  { name: "minAmountOut", type: "uint256" },
2902
2937
  { name: "aggregator", type: "address" },
2903
2938
  { name: "swapData", type: "bytes" },
2939
+ { name: "feeConvertAggregator", type: "address" },
2940
+ { name: "feeSwapData", type: "bytes" },
2941
+ { name: "deadline", type: "uint256" }
2942
+ ],
2943
+ outputs: [{ type: "uint256" }],
2944
+ stateMutability: "nonpayable"
2945
+ },
2946
+ // Base asset → TOKEN (fee from input)
2947
+ {
2948
+ type: "function",
2949
+ name: "executeSwapSimple",
2950
+ inputs: [
2951
+ { name: "tokenIn", type: "address" },
2952
+ { name: "tokenOut", type: "address" },
2953
+ { name: "amountIn", type: "uint256" },
2954
+ { name: "minAmountOut", type: "uint256" },
2955
+ { name: "target", type: "address" },
2956
+ { name: "data", type: "bytes" },
2957
+ { name: "feeConvertAggregator", type: "address" },
2958
+ { name: "feeSwapData", type: "bytes" },
2959
+ { name: "deadline", type: "uint256" }
2960
+ ],
2961
+ outputs: [{ type: "uint256" }],
2962
+ stateMutability: "nonpayable"
2963
+ },
2964
+ // TOKEN → TOKEN (multi-hop via USDC, fee at midpoint)
2965
+ {
2966
+ type: "function",
2967
+ name: "executeSwapMultiHop",
2968
+ inputs: [
2969
+ { name: "tokenIn", type: "address" },
2970
+ { name: "tokenOut", type: "address" },
2971
+ { name: "amountIn", type: "uint256" },
2972
+ { name: "minAmountOut", type: "uint256" },
2973
+ { name: "aggregator1", type: "address" },
2974
+ { name: "swapData1", type: "bytes" },
2975
+ { name: "aggregator2", type: "address" },
2976
+ { name: "swapData2", type: "bytes" },
2904
2977
  { name: "deadline", type: "uint256" }
2905
2978
  ],
2906
2979
  outputs: [{ type: "uint256" }],
@@ -3166,8 +3239,9 @@ var VaultManager = class {
3166
3239
  }
3167
3240
  }
3168
3241
  /**
3169
- * Execute a trade through the vault (if it exists and policy allows)
3170
- * Returns null if should use direct trading instead
3242
+ * Execute a trade through the vault using API-provided vaultParams.
3243
+ * Dispatches to the correct vault function based on swapType.
3244
+ * Returns null if vault trading shouldn't be used (no vault, policy disabled).
3171
3245
  */
3172
3246
  async executeVaultTrade(params) {
3173
3247
  if (!this.preferVaultTrading) {
@@ -3178,23 +3252,71 @@ var VaultManager = class {
3178
3252
  return null;
3179
3253
  }
3180
3254
  const deadline = params.deadline || BigInt(Math.floor(Date.now() / 1e3) + 3600);
3255
+ const { vaultParams } = params;
3181
3256
  try {
3182
- const hash = await this.walletClient.writeContract({
3183
- address: vaultAddress,
3184
- abi: VAULT_ABI,
3185
- functionName: "executeTrade",
3186
- args: [
3187
- params.tokenIn,
3188
- params.tokenOut,
3189
- params.amountIn,
3190
- params.minAmountOut,
3191
- params.aggregator,
3192
- params.swapData,
3193
- deadline
3194
- ],
3195
- chain: import_chains2.base,
3196
- account: this.account
3197
- });
3257
+ let hash;
3258
+ switch (vaultParams.swapType) {
3259
+ case "swap":
3260
+ hash = await this.walletClient.writeContract({
3261
+ address: vaultAddress,
3262
+ abi: VAULT_ABI,
3263
+ functionName: "executeSwap",
3264
+ args: [
3265
+ params.tokenIn,
3266
+ params.tokenOut,
3267
+ params.amountIn,
3268
+ params.minAmountOut,
3269
+ vaultParams.aggregator,
3270
+ vaultParams.swapData,
3271
+ vaultParams.feeConvertAggregator,
3272
+ vaultParams.feeSwapData,
3273
+ deadline
3274
+ ],
3275
+ chain: import_chains2.base,
3276
+ account: this.account
3277
+ });
3278
+ break;
3279
+ case "simple":
3280
+ hash = await this.walletClient.writeContract({
3281
+ address: vaultAddress,
3282
+ abi: VAULT_ABI,
3283
+ functionName: "executeSwapSimple",
3284
+ args: [
3285
+ params.tokenIn,
3286
+ params.tokenOut,
3287
+ params.amountIn,
3288
+ params.minAmountOut,
3289
+ vaultParams.target,
3290
+ vaultParams.data,
3291
+ vaultParams.feeConvertAggregator,
3292
+ vaultParams.feeSwapData,
3293
+ deadline
3294
+ ],
3295
+ chain: import_chains2.base,
3296
+ account: this.account
3297
+ });
3298
+ break;
3299
+ case "multihop":
3300
+ hash = await this.walletClient.writeContract({
3301
+ address: vaultAddress,
3302
+ abi: VAULT_ABI,
3303
+ functionName: "executeSwapMultiHop",
3304
+ args: [
3305
+ params.tokenIn,
3306
+ params.tokenOut,
3307
+ params.amountIn,
3308
+ params.minAmountOut,
3309
+ vaultParams.aggregator1,
3310
+ vaultParams.swapData1,
3311
+ vaultParams.aggregator2,
3312
+ vaultParams.swapData2,
3313
+ deadline
3314
+ ],
3315
+ chain: import_chains2.base,
3316
+ account: this.account
3317
+ });
3318
+ break;
3319
+ }
3198
3320
  return { usedVault: true, txHash: hash };
3199
3321
  } catch (error) {
3200
3322
  return {
@@ -7337,10 +7459,16 @@ var AgentRuntime = class {
7337
7459
  vaultConfig
7338
7460
  });
7339
7461
  console.log(`Vault policy: ${vaultConfig.policy}`);
7462
+ if (this.executor) {
7463
+ this.executor.setVaultManager(this.vaultManager);
7464
+ }
7340
7465
  const status = await this.vaultManager.getVaultStatus();
7341
7466
  if (status.hasVault) {
7342
7467
  console.log(`Vault exists: ${status.vaultAddress}`);
7343
7468
  console.log(`Vault TVL: ${Number(status.totalAssets) / 1e6} USDC`);
7469
+ if (vaultConfig.preferVaultTrading) {
7470
+ console.log("Vault trading enabled \u2014 trades will execute from vault");
7471
+ }
7344
7472
  } else {
7345
7473
  console.log("No vault exists for this agent");
7346
7474
  if (vaultConfig.policy === "manual") {
@@ -8761,8 +8889,9 @@ This exit has been recorded in your trade history and counts toward your total P
8761
8889
  this.paperPortfolio.save();
8762
8890
  } else {
8763
8891
  const vaultStatus = await this.vaultManager?.getVaultStatus();
8764
- if (vaultStatus?.hasVault && this.vaultManager?.preferVaultTrading) {
8765
- console.log(`Trading through vault: ${vaultStatus.vaultAddress}`);
8892
+ if (vaultStatus?.hasVault) {
8893
+ const via = this.vaultManager?.preferVaultTrading ? "vault" : "wallet";
8894
+ console.log(`Vault active: ${vaultStatus.vaultAddress} (trades execute from ${via})`);
8766
8895
  }
8767
8896
  const results = await this.executor.executeAll(filteredSignals);
8768
8897
  let totalFeesUSD = 0;
@@ -9481,7 +9610,7 @@ function loadSecureEnv(basePath, passphrase) {
9481
9610
  }
9482
9611
 
9483
9612
  // src/index.ts
9484
- var AGENT_VERSION = "0.1.46";
9613
+ var AGENT_VERSION = "0.1.47";
9485
9614
  // Annotate the CommonJS export names for ESM import in node:
9486
9615
  0 && (module.exports = {
9487
9616
  AGENT_VERSION,