@exagent/agent 0.1.45 → 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
@@ -548,6 +548,30 @@ var init_market = __esm({
548
548
  }
549
549
  };
550
550
  }
551
+ /**
552
+ * Discover all ERC-20 token holdings for a wallet via Blockscout API.
553
+ * Returns token addresses with non-zero balances.
554
+ * Used by Frontier agents to find tokens outside the standard whitelist.
555
+ */
556
+ async discoverTokenHoldings(walletAddress) {
557
+ try {
558
+ const resp = await fetch(
559
+ `https://base.blockscout.com/api/v2/addresses/${walletAddress}/token-balances`,
560
+ { signal: AbortSignal.timeout(1e4) }
561
+ );
562
+ if (!resp.ok) return [];
563
+ const data = await resp.json();
564
+ const addresses = [];
565
+ for (const entry of data) {
566
+ if (entry.token?.type === "ERC-20" && entry.value && entry.value !== "0") {
567
+ addresses.push(entry.token.address.toLowerCase());
568
+ }
569
+ }
570
+ return addresses;
571
+ } catch {
572
+ return [];
573
+ }
574
+ }
551
575
  /**
552
576
  * Check if cached prices are still fresh
553
577
  */
@@ -1528,16 +1552,25 @@ var init_executor = __esm({
1528
1552
  config;
1529
1553
  allowedTokens;
1530
1554
  configHashFn;
1531
- constructor(client, config, configHashFn) {
1555
+ vaultManager;
1556
+ constructor(client, config, configHashFn, vaultManager) {
1532
1557
  this.client = client;
1533
1558
  this.config = config;
1534
1559
  this.configHashFn = configHashFn;
1560
+ this.vaultManager = vaultManager;
1535
1561
  this.allowedTokens = new Set(
1536
1562
  (config.allowedTokens || []).map((t) => t.toLowerCase())
1537
1563
  );
1538
1564
  }
1539
1565
  /**
1540
- * 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.
1541
1574
  */
1542
1575
  async execute(signal) {
1543
1576
  if (signal.action === "hold") {
@@ -1550,13 +1583,38 @@ var init_executor = __esm({
1550
1583
  return { success: false, error: "Signal exceeds position limits" };
1551
1584
  }
1552
1585
  const configHash = this.configHashFn?.();
1553
- const result = await this.client.trade({
1586
+ const tradeIntent = {
1554
1587
  tokenIn: signal.tokenIn,
1555
1588
  tokenOut: signal.tokenOut,
1556
1589
  amountIn: signal.amountIn,
1557
1590
  maxSlippageBps: this.config.trading?.maxSlippageBps ?? 100,
1558
1591
  ...configHash && { configHash }
1559
- });
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);
1560
1618
  console.log(`Trade executed: ${result.hash}`);
1561
1619
  return { success: true, txHash: result.hash };
1562
1620
  } catch (error) {
@@ -4364,9 +4422,10 @@ var VAULT_ABI = [
4364
4422
  outputs: [{ type: "uint256" }],
4365
4423
  stateMutability: "view"
4366
4424
  },
4425
+ // TOKEN → base asset (fee from output)
4367
4426
  {
4368
4427
  type: "function",
4369
- name: "executeTrade",
4428
+ name: "executeSwap",
4370
4429
  inputs: [
4371
4430
  { name: "tokenIn", type: "address" },
4372
4431
  { name: "tokenOut", type: "address" },
@@ -4374,6 +4433,44 @@ var VAULT_ABI = [
4374
4433
  { name: "minAmountOut", type: "uint256" },
4375
4434
  { name: "aggregator", type: "address" },
4376
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" },
4377
4474
  { name: "deadline", type: "uint256" }
4378
4475
  ],
4379
4476
  outputs: [{ type: "uint256" }],
@@ -4639,8 +4736,9 @@ var VaultManager = class {
4639
4736
  }
4640
4737
  }
4641
4738
  /**
4642
- * Execute a trade through the vault (if it exists and policy allows)
4643
- * 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).
4644
4742
  */
4645
4743
  async executeVaultTrade(params) {
4646
4744
  if (!this.preferVaultTrading) {
@@ -4651,23 +4749,71 @@ var VaultManager = class {
4651
4749
  return null;
4652
4750
  }
4653
4751
  const deadline = params.deadline || BigInt(Math.floor(Date.now() / 1e3) + 3600);
4752
+ const { vaultParams } = params;
4654
4753
  try {
4655
- const hash = await this.walletClient.writeContract({
4656
- address: vaultAddress,
4657
- abi: VAULT_ABI,
4658
- functionName: "executeTrade",
4659
- args: [
4660
- params.tokenIn,
4661
- params.tokenOut,
4662
- params.amountIn,
4663
- params.minAmountOut,
4664
- params.aggregator,
4665
- params.swapData,
4666
- deadline
4667
- ],
4668
- chain: import_chains2.base,
4669
- account: this.account
4670
- });
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
+ }
4671
4817
  return { usedVault: true, txHash: hash };
4672
4818
  } catch (error) {
4673
4819
  return {
@@ -7925,7 +8071,7 @@ function loadSecureEnv(basePath, passphrase) {
7925
8071
  }
7926
8072
 
7927
8073
  // src/index.ts
7928
- var AGENT_VERSION = "0.1.45";
8074
+ var AGENT_VERSION = "0.1.47";
7929
8075
 
7930
8076
  // src/relay.ts
7931
8077
  var RelayClient = class {
@@ -8221,6 +8367,8 @@ var AgentRuntime = class {
8221
8367
  processAlive = true;
8222
8368
  riskUniverse = 0;
8223
8369
  allowedTokens = /* @__PURE__ */ new Set();
8370
+ /** Frontier token discovery — cached addresses from Blockscout scan */
8371
+ discoveredTokens = [];
8224
8372
  strategyContext;
8225
8373
  positionTracker;
8226
8374
  // Paper trading components (null when not in paper mode)
@@ -8384,10 +8532,16 @@ var AgentRuntime = class {
8384
8532
  vaultConfig
8385
8533
  });
8386
8534
  console.log(`Vault policy: ${vaultConfig.policy}`);
8535
+ if (this.executor) {
8536
+ this.executor.setVaultManager(this.vaultManager);
8537
+ }
8387
8538
  const status = await this.vaultManager.getVaultStatus();
8388
8539
  if (status.hasVault) {
8389
8540
  console.log(`Vault exists: ${status.vaultAddress}`);
8390
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
+ }
8391
8545
  } else {
8392
8546
  console.log("No vault exists for this agent");
8393
8547
  if (vaultConfig.policy === "manual") {
@@ -8822,6 +8976,13 @@ var AgentRuntime = class {
8822
8976
  console.log("");
8823
8977
  this.mode = "idle";
8824
8978
  try {
8979
+ if (this.riskUniverse === 4) {
8980
+ const discovered = await this.marketData.discoverTokenHoldings(this.client.address);
8981
+ if (discovered.length > 0) {
8982
+ this.discoveredTokens = discovered;
8983
+ console.log(`Frontier token discovery: ${discovered.length} token(s) found on-chain`);
8984
+ }
8985
+ }
8825
8986
  const tokens = this.getTokensToTrack();
8826
8987
  const initData = await this.marketData.fetchMarketData(this.client.address, tokens);
8827
8988
  void this.positionTracker.syncBalances(initData.balances, initData.prices);
@@ -9801,8 +9962,9 @@ This exit has been recorded in your trade history and counts toward your total P
9801
9962
  this.paperPortfolio.save();
9802
9963
  } else {
9803
9964
  const vaultStatus = await this.vaultManager?.getVaultStatus();
9804
- if (vaultStatus?.hasVault && this.vaultManager?.preferVaultTrading) {
9805
- 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})`);
9806
9968
  }
9807
9969
  const results = await this.executor.executeAll(filteredSignals);
9808
9970
  let totalFeesUSD = 0;
@@ -10174,8 +10336,14 @@ See: https://exagent.io/docs/guides/manual-exit`,
10174
10336
  }
10175
10337
  }
10176
10338
  }
10339
+ for (const addr of this.discoveredTokens) {
10340
+ if (!baseSet.has(addr)) {
10341
+ extras.push(addr);
10342
+ baseSet.add(addr);
10343
+ }
10344
+ }
10177
10345
  if (extras.length > 0) {
10178
- console.log(`Auto-tracking ${extras.length} additional token(s) from position history`);
10346
+ console.log(`Auto-tracking ${extras.length} additional token(s) from position/discovery`);
10179
10347
  }
10180
10348
  const resolver = this.marketData.getResolver();
10181
10349
  const allTokens = [...base8, ...extras];
package/dist/cli.mjs CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  results_exports,
30
30
  saveSessionResult,
31
31
  validateConfig
32
- } from "./chunk-RR4RQDU3.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;
@@ -1133,6 +1133,8 @@ declare class AgentRuntime {
1133
1133
  private processAlive;
1134
1134
  private riskUniverse;
1135
1135
  private allowedTokens;
1136
+ /** Frontier token discovery — cached addresses from Blockscout scan */
1137
+ private discoveredTokens;
1136
1138
  private strategyContext;
1137
1139
  private positionTracker;
1138
1140
  private paperExecutor;
@@ -1536,17 +1538,23 @@ declare function getAllStrategyTemplates(): StrategyTemplate[];
1536
1538
  /**
1537
1539
  * Trade Executor
1538
1540
  * Handles execution of trade signals through the ExagentRouter.
1539
- * All trades go through the router there is no direct DEX bypass.
1540
- * 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.
1541
1543
  */
1542
1544
  declare class TradeExecutor {
1543
1545
  private client;
1544
1546
  private config;
1545
1547
  private allowedTokens;
1546
1548
  private configHashFn?;
1547
- constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string);
1549
+ private vaultManager?;
1550
+ constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string, vaultManager?: VaultManager);
1548
1551
  /**
1549
- * 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.
1550
1558
  */
1551
1559
  execute(signal: TradeSignal): Promise<{
1552
1560
  success: boolean;
@@ -1948,6 +1956,12 @@ declare class MarketDataService {
1948
1956
  * Fetch current market data for the agent
1949
1957
  */
1950
1958
  fetchMarketData(walletAddress: string, tokenAddresses: string[]): Promise<MarketData>;
1959
+ /**
1960
+ * Discover all ERC-20 token holdings for a wallet via Blockscout API.
1961
+ * Returns token addresses with non-zero balances.
1962
+ * Used by Frontier agents to find tokens outside the standard whitelist.
1963
+ */
1964
+ discoverTokenHoldings(walletAddress: string): Promise<string[]>;
1951
1965
  /**
1952
1966
  * Check if cached prices are still fresh
1953
1967
  */
@@ -3345,6 +3359,6 @@ declare function decryptEnvFile(encPath: string, passphrase: string): Record<str
3345
3359
  declare function loadSecureEnv(basePath: string, passphrase?: string): boolean;
3346
3360
 
3347
3361
  /** @exagent/agent package version — update alongside package.json */
3348
- declare const AGENT_VERSION = "0.1.45";
3362
+ declare const AGENT_VERSION = "0.1.47";
3349
3363
 
3350
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;
@@ -1133,6 +1133,8 @@ declare class AgentRuntime {
1133
1133
  private processAlive;
1134
1134
  private riskUniverse;
1135
1135
  private allowedTokens;
1136
+ /** Frontier token discovery — cached addresses from Blockscout scan */
1137
+ private discoveredTokens;
1136
1138
  private strategyContext;
1137
1139
  private positionTracker;
1138
1140
  private paperExecutor;
@@ -1536,17 +1538,23 @@ declare function getAllStrategyTemplates(): StrategyTemplate[];
1536
1538
  /**
1537
1539
  * Trade Executor
1538
1540
  * Handles execution of trade signals through the ExagentRouter.
1539
- * All trades go through the router there is no direct DEX bypass.
1540
- * 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.
1541
1543
  */
1542
1544
  declare class TradeExecutor {
1543
1545
  private client;
1544
1546
  private config;
1545
1547
  private allowedTokens;
1546
1548
  private configHashFn?;
1547
- constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string);
1549
+ private vaultManager?;
1550
+ constructor(client: ExagentClient, config: RuntimeConfig, configHashFn?: () => string, vaultManager?: VaultManager);
1548
1551
  /**
1549
- * 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.
1550
1558
  */
1551
1559
  execute(signal: TradeSignal): Promise<{
1552
1560
  success: boolean;
@@ -1948,6 +1956,12 @@ declare class MarketDataService {
1948
1956
  * Fetch current market data for the agent
1949
1957
  */
1950
1958
  fetchMarketData(walletAddress: string, tokenAddresses: string[]): Promise<MarketData>;
1959
+ /**
1960
+ * Discover all ERC-20 token holdings for a wallet via Blockscout API.
1961
+ * Returns token addresses with non-zero balances.
1962
+ * Used by Frontier agents to find tokens outside the standard whitelist.
1963
+ */
1964
+ discoverTokenHoldings(walletAddress: string): Promise<string[]>;
1951
1965
  /**
1952
1966
  * Check if cached prices are still fresh
1953
1967
  */
@@ -3345,6 +3359,6 @@ declare function decryptEnvFile(encPath: string, passphrase: string): Record<str
3345
3359
  declare function loadSecureEnv(basePath: string, passphrase?: string): boolean;
3346
3360
 
3347
3361
  /** @exagent/agent package version — update alongside package.json */
3348
- declare const AGENT_VERSION = "0.1.45";
3362
+ declare const AGENT_VERSION = "0.1.47";
3349
3363
 
3350
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 };