@exagent/agent 0.1.8 → 0.1.10

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
@@ -32,7 +32,7 @@ var path2 = __toESM(require("path"));
32
32
 
33
33
  // src/runtime.ts
34
34
  var import_sdk = require("@exagent/sdk");
35
- var import_viem2 = require("viem");
35
+ var import_viem3 = require("viem");
36
36
  var import_chains2 = require("viem/chains");
37
37
 
38
38
  // src/llm/openai.ts
@@ -980,10 +980,22 @@ var RiskManager = class {
980
980
  };
981
981
 
982
982
  // src/trading/market.ts
983
+ var import_viem = require("viem");
984
+ var NATIVE_ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
985
+ var USDC_DECIMALS = {
986
+ "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": 6,
987
+ // USDC on Base
988
+ "0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca": 6
989
+ // USDbC on Base
990
+ };
983
991
  var MarketDataService = class {
984
992
  rpcUrl;
993
+ client;
985
994
  constructor(rpcUrl) {
986
995
  this.rpcUrl = rpcUrl;
996
+ this.client = (0, import_viem.createPublicClient)({
997
+ transport: (0, import_viem.http)(rpcUrl)
998
+ });
987
999
  }
988
1000
  /**
989
1001
  * Fetch current market data for the agent
@@ -1005,25 +1017,53 @@ var MarketDataService = class {
1005
1017
  async fetchPrices(tokenAddresses) {
1006
1018
  const prices = {};
1007
1019
  const knownPrices = {
1020
+ // Native ETH (sentinel address)
1021
+ [NATIVE_ETH.toLowerCase()]: 3500,
1008
1022
  // WETH
1009
1023
  "0x4200000000000000000000000000000000000006": 3500,
1010
1024
  // USDC
1011
- "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": 1,
1025
+ "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": 1,
1012
1026
  // USDbC (bridged USDC)
1013
- "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA": 1
1027
+ "0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca": 1
1014
1028
  };
1029
+ prices[NATIVE_ETH.toLowerCase()] = knownPrices[NATIVE_ETH.toLowerCase()];
1015
1030
  for (const address of tokenAddresses) {
1016
1031
  prices[address.toLowerCase()] = knownPrices[address.toLowerCase()] || 0;
1017
1032
  }
1018
1033
  return prices;
1019
1034
  }
1020
1035
  /**
1021
- * Fetch token balances from chain
1036
+ * Fetch real on-chain balances: native ETH + ERC-20 tokens
1022
1037
  */
1023
1038
  async fetchBalances(walletAddress, tokenAddresses) {
1024
1039
  const balances = {};
1025
- for (const address of tokenAddresses) {
1026
- balances[address.toLowerCase()] = 0n;
1040
+ const wallet = walletAddress;
1041
+ try {
1042
+ const nativeBalance = await this.client.getBalance({ address: wallet });
1043
+ balances[NATIVE_ETH.toLowerCase()] = nativeBalance;
1044
+ const erc20Promises = tokenAddresses.map(async (tokenAddress) => {
1045
+ try {
1046
+ const balance = await this.client.readContract({
1047
+ address: tokenAddress,
1048
+ abi: import_viem.erc20Abi,
1049
+ functionName: "balanceOf",
1050
+ args: [wallet]
1051
+ });
1052
+ return { address: tokenAddress.toLowerCase(), balance };
1053
+ } catch (error) {
1054
+ return { address: tokenAddress.toLowerCase(), balance: 0n };
1055
+ }
1056
+ });
1057
+ const results = await Promise.all(erc20Promises);
1058
+ for (const { address, balance } of results) {
1059
+ balances[address] = balance;
1060
+ }
1061
+ } catch (error) {
1062
+ console.error("MarketData: Failed to fetch balances:", error instanceof Error ? error.message : error);
1063
+ balances[NATIVE_ETH.toLowerCase()] = 0n;
1064
+ for (const address of tokenAddresses) {
1065
+ balances[address.toLowerCase()] = 0n;
1066
+ }
1027
1067
  }
1028
1068
  return balances;
1029
1069
  }
@@ -1034,7 +1074,8 @@ var MarketDataService = class {
1034
1074
  let total = 0;
1035
1075
  for (const [address, balance] of Object.entries(balances)) {
1036
1076
  const price = prices[address.toLowerCase()] || 0;
1037
- const amount = Number(balance) / 1e18;
1077
+ const decimals = USDC_DECIMALS[address.toLowerCase()] || 18;
1078
+ const amount = Number(balance) / Math.pow(10, decimals);
1038
1079
  total += amount * price;
1039
1080
  }
1040
1081
  return total;
@@ -1042,7 +1083,7 @@ var MarketDataService = class {
1042
1083
  };
1043
1084
 
1044
1085
  // src/vault/manager.ts
1045
- var import_viem = require("viem");
1086
+ var import_viem2 = require("viem");
1046
1087
  var import_accounts = require("viem/accounts");
1047
1088
  var import_chains = require("viem/chains");
1048
1089
  var ADDRESSES = {
@@ -1145,14 +1186,14 @@ var VaultManager = class {
1145
1186
  this.account = (0, import_accounts.privateKeyToAccount)(config.walletKey);
1146
1187
  this.chain = config.network === "mainnet" ? import_chains.base : import_chains.baseSepolia;
1147
1188
  const rpcUrl = config.network === "mainnet" ? "https://mainnet.base.org" : "https://sepolia.base.org";
1148
- this.publicClient = (0, import_viem.createPublicClient)({
1189
+ this.publicClient = (0, import_viem2.createPublicClient)({
1149
1190
  chain: this.chain,
1150
- transport: (0, import_viem.http)(rpcUrl)
1191
+ transport: (0, import_viem2.http)(rpcUrl)
1151
1192
  });
1152
- this.walletClient = (0, import_viem.createWalletClient)({
1193
+ this.walletClient = (0, import_viem2.createWalletClient)({
1153
1194
  account: this.account,
1154
1195
  chain: this.chain,
1155
- transport: (0, import_viem.http)(rpcUrl)
1196
+ transport: (0, import_viem2.http)(rpcUrl)
1156
1197
  });
1157
1198
  }
1158
1199
  /**
@@ -1664,6 +1705,8 @@ var AgentRuntime = class {
1664
1705
  lastVaultCheck = 0;
1665
1706
  cycleCount = 0;
1666
1707
  lastCycleAt = 0;
1708
+ lastPortfolioValue = 0;
1709
+ lastEthBalance = "0";
1667
1710
  processAlive = true;
1668
1711
  VAULT_CHECK_INTERVAL = 3e5;
1669
1712
  // Check vault status every 5 minutes
@@ -1839,9 +1882,9 @@ var AgentRuntime = class {
1839
1882
  if (message.includes("insufficient funds") || message.includes("gas") || message.includes("intrinsic gas too low") || message.includes("exceeds the balance")) {
1840
1883
  const ccUrl = `https://exagent.io/agents/${encodeURIComponent(this.config.name)}/command-center`;
1841
1884
  const chain = this.config.network === "mainnet" ? import_chains2.base : import_chains2.baseSepolia;
1842
- const publicClientInstance = (0, import_viem2.createPublicClient)({
1885
+ const publicClientInstance = (0, import_viem3.createPublicClient)({
1843
1886
  chain,
1844
- transport: (0, import_viem2.http)(this.getRpcUrl())
1887
+ transport: (0, import_viem3.http)(this.getRpcUrl())
1845
1888
  });
1846
1889
  console.log("");
1847
1890
  console.log("=== ETH NEEDED FOR GAS ===");
@@ -2074,6 +2117,8 @@ var AgentRuntime = class {
2074
2117
  cycleCount: this.cycleCount,
2075
2118
  lastCycleAt: this.lastCycleAt,
2076
2119
  tradingIntervalMs: this.config.trading.tradingIntervalMs,
2120
+ portfolioValue: this.lastPortfolioValue,
2121
+ ethBalance: this.lastEthBalance,
2077
2122
  llm: {
2078
2123
  provider: this.config.llm.provider,
2079
2124
  model: this.config.llm.model || "default"
@@ -2103,6 +2148,9 @@ var AgentRuntime = class {
2103
2148
  const tokens = this.config.allowedTokens || this.getDefaultTokens();
2104
2149
  const marketData = await this.marketData.fetchMarketData(this.client.address, tokens);
2105
2150
  console.log(`Portfolio value: $${marketData.portfolioValue.toFixed(2)}`);
2151
+ this.lastPortfolioValue = marketData.portfolioValue;
2152
+ const nativeEthBal = marketData.balances[NATIVE_ETH.toLowerCase()] || BigInt(0);
2153
+ this.lastEthBalance = (Number(nativeEthBal) / 1e18).toFixed(6);
2106
2154
  this.checkFundsLow(marketData);
2107
2155
  let signals;
2108
2156
  try {
@@ -2165,8 +2213,7 @@ var AgentRuntime = class {
2165
2213
  */
2166
2214
  checkFundsLow(marketData) {
2167
2215
  if (!this.relay) return;
2168
- const wethAddress = "0x4200000000000000000000000000000000000006";
2169
- const ethBalance = marketData.balances[wethAddress] || BigInt(0);
2216
+ const ethBalance = marketData.balances[NATIVE_ETH.toLowerCase()] || BigInt(0);
2170
2217
  const ethAmount = Number(ethBalance) / 1e18;
2171
2218
  if (ethAmount < FUNDS_LOW_THRESHOLD) {
2172
2219
  this.relay.sendMessage(
package/dist/cli.mjs CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  loadConfig,
7
7
  loadSecureEnv,
8
8
  validateConfig
9
- } from "./chunk-ONWRXGJG.mjs";
9
+ } from "./chunk-7GQXIIL2.mjs";
10
10
 
11
11
  // src/cli.ts
12
12
  import { Command } from "commander";
package/dist/index.d.mts CHANGED
@@ -467,6 +467,8 @@ declare class AgentRuntime {
467
467
  private lastVaultCheck;
468
468
  private cycleCount;
469
469
  private lastCycleAt;
470
+ private lastPortfolioValue;
471
+ private lastEthBalance;
470
472
  private processAlive;
471
473
  private readonly VAULT_CHECK_INTERVAL;
472
474
  constructor(config: RuntimeConfig);
@@ -816,10 +818,15 @@ declare class RiskManager {
816
818
 
817
819
  /**
818
820
  * Market Data Service
819
- * Fetches prices and portfolio data for strategy analysis
821
+ * Fetches prices and portfolio data for strategy analysis.
822
+ *
823
+ * Queries real on-chain balances for:
824
+ * - Native ETH (via eth_getBalance)
825
+ * - ERC-20 tokens (via balanceOf)
820
826
  */
821
827
  declare class MarketDataService {
822
828
  private rpcUrl;
829
+ private client;
823
830
  constructor(rpcUrl: string);
824
831
  /**
825
832
  * Fetch current market data for the agent
@@ -830,7 +837,7 @@ declare class MarketDataService {
830
837
  */
831
838
  private fetchPrices;
832
839
  /**
833
- * Fetch token balances from chain
840
+ * Fetch real on-chain balances: native ETH + ERC-20 tokens
834
841
  */
835
842
  private fetchBalances;
836
843
  /**
package/dist/index.d.ts CHANGED
@@ -467,6 +467,8 @@ declare class AgentRuntime {
467
467
  private lastVaultCheck;
468
468
  private cycleCount;
469
469
  private lastCycleAt;
470
+ private lastPortfolioValue;
471
+ private lastEthBalance;
470
472
  private processAlive;
471
473
  private readonly VAULT_CHECK_INTERVAL;
472
474
  constructor(config: RuntimeConfig);
@@ -816,10 +818,15 @@ declare class RiskManager {
816
818
 
817
819
  /**
818
820
  * Market Data Service
819
- * Fetches prices and portfolio data for strategy analysis
821
+ * Fetches prices and portfolio data for strategy analysis.
822
+ *
823
+ * Queries real on-chain balances for:
824
+ * - Native ETH (via eth_getBalance)
825
+ * - ERC-20 tokens (via balanceOf)
820
826
  */
821
827
  declare class MarketDataService {
822
828
  private rpcUrl;
829
+ private client;
823
830
  constructor(rpcUrl: string);
824
831
  /**
825
832
  * Fetch current market data for the agent
@@ -830,7 +837,7 @@ declare class MarketDataService {
830
837
  */
831
838
  private fetchPrices;
832
839
  /**
833
- * Fetch token balances from chain
840
+ * Fetch real on-chain balances: native ETH + ERC-20 tokens
834
841
  */
835
842
  private fetchBalances;
836
843
  /**
package/dist/index.js CHANGED
@@ -70,7 +70,7 @@ module.exports = __toCommonJS(index_exports);
70
70
 
71
71
  // src/runtime.ts
72
72
  var import_sdk = require("@exagent/sdk");
73
- var import_viem2 = require("viem");
73
+ var import_viem3 = require("viem");
74
74
  var import_chains2 = require("viem/chains");
75
75
 
76
76
  // src/llm/openai.ts
@@ -1024,10 +1024,22 @@ var RiskManager = class {
1024
1024
  };
1025
1025
 
1026
1026
  // src/trading/market.ts
1027
+ var import_viem = require("viem");
1028
+ var NATIVE_ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
1029
+ var USDC_DECIMALS = {
1030
+ "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": 6,
1031
+ // USDC on Base
1032
+ "0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca": 6
1033
+ // USDbC on Base
1034
+ };
1027
1035
  var MarketDataService = class {
1028
1036
  rpcUrl;
1037
+ client;
1029
1038
  constructor(rpcUrl) {
1030
1039
  this.rpcUrl = rpcUrl;
1040
+ this.client = (0, import_viem.createPublicClient)({
1041
+ transport: (0, import_viem.http)(rpcUrl)
1042
+ });
1031
1043
  }
1032
1044
  /**
1033
1045
  * Fetch current market data for the agent
@@ -1049,25 +1061,53 @@ var MarketDataService = class {
1049
1061
  async fetchPrices(tokenAddresses) {
1050
1062
  const prices = {};
1051
1063
  const knownPrices = {
1064
+ // Native ETH (sentinel address)
1065
+ [NATIVE_ETH.toLowerCase()]: 3500,
1052
1066
  // WETH
1053
1067
  "0x4200000000000000000000000000000000000006": 3500,
1054
1068
  // USDC
1055
- "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": 1,
1069
+ "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": 1,
1056
1070
  // USDbC (bridged USDC)
1057
- "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA": 1
1071
+ "0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca": 1
1058
1072
  };
1073
+ prices[NATIVE_ETH.toLowerCase()] = knownPrices[NATIVE_ETH.toLowerCase()];
1059
1074
  for (const address of tokenAddresses) {
1060
1075
  prices[address.toLowerCase()] = knownPrices[address.toLowerCase()] || 0;
1061
1076
  }
1062
1077
  return prices;
1063
1078
  }
1064
1079
  /**
1065
- * Fetch token balances from chain
1080
+ * Fetch real on-chain balances: native ETH + ERC-20 tokens
1066
1081
  */
1067
1082
  async fetchBalances(walletAddress, tokenAddresses) {
1068
1083
  const balances = {};
1069
- for (const address of tokenAddresses) {
1070
- balances[address.toLowerCase()] = 0n;
1084
+ const wallet = walletAddress;
1085
+ try {
1086
+ const nativeBalance = await this.client.getBalance({ address: wallet });
1087
+ balances[NATIVE_ETH.toLowerCase()] = nativeBalance;
1088
+ const erc20Promises = tokenAddresses.map(async (tokenAddress) => {
1089
+ try {
1090
+ const balance = await this.client.readContract({
1091
+ address: tokenAddress,
1092
+ abi: import_viem.erc20Abi,
1093
+ functionName: "balanceOf",
1094
+ args: [wallet]
1095
+ });
1096
+ return { address: tokenAddress.toLowerCase(), balance };
1097
+ } catch (error) {
1098
+ return { address: tokenAddress.toLowerCase(), balance: 0n };
1099
+ }
1100
+ });
1101
+ const results = await Promise.all(erc20Promises);
1102
+ for (const { address, balance } of results) {
1103
+ balances[address] = balance;
1104
+ }
1105
+ } catch (error) {
1106
+ console.error("MarketData: Failed to fetch balances:", error instanceof Error ? error.message : error);
1107
+ balances[NATIVE_ETH.toLowerCase()] = 0n;
1108
+ for (const address of tokenAddresses) {
1109
+ balances[address.toLowerCase()] = 0n;
1110
+ }
1071
1111
  }
1072
1112
  return balances;
1073
1113
  }
@@ -1078,7 +1118,8 @@ var MarketDataService = class {
1078
1118
  let total = 0;
1079
1119
  for (const [address, balance] of Object.entries(balances)) {
1080
1120
  const price = prices[address.toLowerCase()] || 0;
1081
- const amount = Number(balance) / 1e18;
1121
+ const decimals = USDC_DECIMALS[address.toLowerCase()] || 18;
1122
+ const amount = Number(balance) / Math.pow(10, decimals);
1082
1123
  total += amount * price;
1083
1124
  }
1084
1125
  return total;
@@ -1086,7 +1127,7 @@ var MarketDataService = class {
1086
1127
  };
1087
1128
 
1088
1129
  // src/vault/manager.ts
1089
- var import_viem = require("viem");
1130
+ var import_viem2 = require("viem");
1090
1131
  var import_accounts = require("viem/accounts");
1091
1132
  var import_chains = require("viem/chains");
1092
1133
  var ADDRESSES = {
@@ -1189,14 +1230,14 @@ var VaultManager = class {
1189
1230
  this.account = (0, import_accounts.privateKeyToAccount)(config.walletKey);
1190
1231
  this.chain = config.network === "mainnet" ? import_chains.base : import_chains.baseSepolia;
1191
1232
  const rpcUrl = config.network === "mainnet" ? "https://mainnet.base.org" : "https://sepolia.base.org";
1192
- this.publicClient = (0, import_viem.createPublicClient)({
1233
+ this.publicClient = (0, import_viem2.createPublicClient)({
1193
1234
  chain: this.chain,
1194
- transport: (0, import_viem.http)(rpcUrl)
1235
+ transport: (0, import_viem2.http)(rpcUrl)
1195
1236
  });
1196
- this.walletClient = (0, import_viem.createWalletClient)({
1237
+ this.walletClient = (0, import_viem2.createWalletClient)({
1197
1238
  account: this.account,
1198
1239
  chain: this.chain,
1199
- transport: (0, import_viem.http)(rpcUrl)
1240
+ transport: (0, import_viem2.http)(rpcUrl)
1200
1241
  });
1201
1242
  }
1202
1243
  /**
@@ -1708,6 +1749,8 @@ var AgentRuntime = class {
1708
1749
  lastVaultCheck = 0;
1709
1750
  cycleCount = 0;
1710
1751
  lastCycleAt = 0;
1752
+ lastPortfolioValue = 0;
1753
+ lastEthBalance = "0";
1711
1754
  processAlive = true;
1712
1755
  VAULT_CHECK_INTERVAL = 3e5;
1713
1756
  // Check vault status every 5 minutes
@@ -1883,9 +1926,9 @@ var AgentRuntime = class {
1883
1926
  if (message.includes("insufficient funds") || message.includes("gas") || message.includes("intrinsic gas too low") || message.includes("exceeds the balance")) {
1884
1927
  const ccUrl = `https://exagent.io/agents/${encodeURIComponent(this.config.name)}/command-center`;
1885
1928
  const chain = this.config.network === "mainnet" ? import_chains2.base : import_chains2.baseSepolia;
1886
- const publicClientInstance = (0, import_viem2.createPublicClient)({
1929
+ const publicClientInstance = (0, import_viem3.createPublicClient)({
1887
1930
  chain,
1888
- transport: (0, import_viem2.http)(this.getRpcUrl())
1931
+ transport: (0, import_viem3.http)(this.getRpcUrl())
1889
1932
  });
1890
1933
  console.log("");
1891
1934
  console.log("=== ETH NEEDED FOR GAS ===");
@@ -2118,6 +2161,8 @@ var AgentRuntime = class {
2118
2161
  cycleCount: this.cycleCount,
2119
2162
  lastCycleAt: this.lastCycleAt,
2120
2163
  tradingIntervalMs: this.config.trading.tradingIntervalMs,
2164
+ portfolioValue: this.lastPortfolioValue,
2165
+ ethBalance: this.lastEthBalance,
2121
2166
  llm: {
2122
2167
  provider: this.config.llm.provider,
2123
2168
  model: this.config.llm.model || "default"
@@ -2147,6 +2192,9 @@ var AgentRuntime = class {
2147
2192
  const tokens = this.config.allowedTokens || this.getDefaultTokens();
2148
2193
  const marketData = await this.marketData.fetchMarketData(this.client.address, tokens);
2149
2194
  console.log(`Portfolio value: $${marketData.portfolioValue.toFixed(2)}`);
2195
+ this.lastPortfolioValue = marketData.portfolioValue;
2196
+ const nativeEthBal = marketData.balances[NATIVE_ETH.toLowerCase()] || BigInt(0);
2197
+ this.lastEthBalance = (Number(nativeEthBal) / 1e18).toFixed(6);
2150
2198
  this.checkFundsLow(marketData);
2151
2199
  let signals;
2152
2200
  try {
@@ -2209,8 +2257,7 @@ var AgentRuntime = class {
2209
2257
  */
2210
2258
  checkFundsLow(marketData) {
2211
2259
  if (!this.relay) return;
2212
- const wethAddress = "0x4200000000000000000000000000000000000006";
2213
- const ethBalance = marketData.balances[wethAddress] || BigInt(0);
2260
+ const ethBalance = marketData.balances[NATIVE_ETH.toLowerCase()] || BigInt(0);
2214
2261
  const ethAmount = Number(ethBalance) / 1e18;
2215
2262
  if (ethAmount < FUNDS_LOW_THRESHOLD) {
2216
2263
  this.relay.sendMessage(
package/dist/index.mjs CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  loadStrategy,
35
35
  validateConfig,
36
36
  validateStrategy
37
- } from "./chunk-ONWRXGJG.mjs";
37
+ } from "./chunk-7GQXIIL2.mjs";
38
38
  export {
39
39
  AgentConfigSchema,
40
40
  AgentRuntime,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exagent/agent",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Autonomous trading agent runtime for Exagent",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",