@exagent/sdk 0.1.16 → 0.1.18

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/index.d.mts CHANGED
@@ -192,6 +192,10 @@ interface RouterTradeResponse {
192
192
  agentId: number;
193
193
  };
194
194
  mock?: boolean;
195
+ /** Present when API's pre-flight simulation failed (for sells) */
196
+ simulationSkipped?: boolean;
197
+ /** Warning message when simulation failed */
198
+ simulationWarning?: string;
195
199
  }
196
200
  /**
197
201
  * Trade execution result
@@ -1083,7 +1087,7 @@ declare class ExagentVault {
1083
1087
  }
1084
1088
 
1085
1089
  /** SDK version — sent to API for version gating */
1086
- declare const SDK_VERSION = "0.1.14";
1090
+ declare const SDK_VERSION = "0.1.18";
1087
1091
  /**
1088
1092
  * Default RPC URL for Base mainnet.
1089
1093
  * Coinbase's official Base RPC — reliable for reads and transactions.
@@ -1575,6 +1579,10 @@ declare class ExagentClient {
1575
1579
  * Useful for simulation or multi-step workflows
1576
1580
  */
1577
1581
  buildRouterTrade(intent: Omit<TradeIntent, 'action'>, agentId?: bigint): Promise<RouterTradeResponse>;
1582
+ /**
1583
+ * Check if an address is the ETH sentinel or WETH
1584
+ */
1585
+ private isETHAddress;
1578
1586
  /**
1579
1587
  * Read current ERC-20 allowance for a (token, spender) pair
1580
1588
  */
@@ -1908,36 +1916,6 @@ declare const EXAGENT_VAULT_FACTORY_ABI: readonly [{
1908
1916
  readonly type: "uint256";
1909
1917
  }];
1910
1918
  readonly stateMutability: "view";
1911
- }, {
1912
- readonly type: "function";
1913
- readonly name: "canCreateVault";
1914
- readonly inputs: readonly [{
1915
- readonly name: "creator";
1916
- readonly type: "address";
1917
- }];
1918
- readonly outputs: readonly [{
1919
- readonly name: "canCreate";
1920
- readonly type: "bool";
1921
- }, {
1922
- readonly name: "reason";
1923
- readonly type: "string";
1924
- }];
1925
- readonly stateMutability: "view";
1926
- }, {
1927
- readonly type: "function";
1928
- readonly name: "canCreateVerifiedVault";
1929
- readonly inputs: readonly [{
1930
- readonly name: "agentId";
1931
- readonly type: "uint256";
1932
- }];
1933
- readonly outputs: readonly [{
1934
- readonly name: "isVerified";
1935
- readonly type: "bool";
1936
- }, {
1937
- readonly name: "reason";
1938
- readonly type: "string";
1939
- }];
1940
- readonly stateMutability: "view";
1941
1919
  }, {
1942
1920
  readonly type: "function";
1943
1921
  readonly name: "createVault";
@@ -2046,18 +2024,12 @@ declare class ExagentVaultFactory {
2046
2024
  */
2047
2025
  getRequirements(): Promise<VaultCreationRequirements>;
2048
2026
  /**
2049
- * Check if an address can create a vault
2027
+ * Check if an address can create a vault.
2028
+ * Performs inline validation since the on-chain contract does not expose
2029
+ * a canCreateVault() view function.
2050
2030
  * @param creator Address to check
2051
2031
  */
2052
2032
  canCreateVault(creator: Address): Promise<CanCreateVaultResult>;
2053
- /**
2054
- * Check if an agent can create a verified vault (higher deposit cap)
2055
- * @param agentId Agent ID to check
2056
- */
2057
- canCreateVerifiedVault(agentId: bigint): Promise<{
2058
- isVerified: boolean;
2059
- reason: string;
2060
- }>;
2061
2033
  /**
2062
2034
  * Check if an asset is whitelisted for vault creation
2063
2035
  * @param asset Asset address to check
package/dist/index.d.ts CHANGED
@@ -192,6 +192,10 @@ interface RouterTradeResponse {
192
192
  agentId: number;
193
193
  };
194
194
  mock?: boolean;
195
+ /** Present when API's pre-flight simulation failed (for sells) */
196
+ simulationSkipped?: boolean;
197
+ /** Warning message when simulation failed */
198
+ simulationWarning?: string;
195
199
  }
196
200
  /**
197
201
  * Trade execution result
@@ -1083,7 +1087,7 @@ declare class ExagentVault {
1083
1087
  }
1084
1088
 
1085
1089
  /** SDK version — sent to API for version gating */
1086
- declare const SDK_VERSION = "0.1.14";
1090
+ declare const SDK_VERSION = "0.1.18";
1087
1091
  /**
1088
1092
  * Default RPC URL for Base mainnet.
1089
1093
  * Coinbase's official Base RPC — reliable for reads and transactions.
@@ -1575,6 +1579,10 @@ declare class ExagentClient {
1575
1579
  * Useful for simulation or multi-step workflows
1576
1580
  */
1577
1581
  buildRouterTrade(intent: Omit<TradeIntent, 'action'>, agentId?: bigint): Promise<RouterTradeResponse>;
1582
+ /**
1583
+ * Check if an address is the ETH sentinel or WETH
1584
+ */
1585
+ private isETHAddress;
1578
1586
  /**
1579
1587
  * Read current ERC-20 allowance for a (token, spender) pair
1580
1588
  */
@@ -1908,36 +1916,6 @@ declare const EXAGENT_VAULT_FACTORY_ABI: readonly [{
1908
1916
  readonly type: "uint256";
1909
1917
  }];
1910
1918
  readonly stateMutability: "view";
1911
- }, {
1912
- readonly type: "function";
1913
- readonly name: "canCreateVault";
1914
- readonly inputs: readonly [{
1915
- readonly name: "creator";
1916
- readonly type: "address";
1917
- }];
1918
- readonly outputs: readonly [{
1919
- readonly name: "canCreate";
1920
- readonly type: "bool";
1921
- }, {
1922
- readonly name: "reason";
1923
- readonly type: "string";
1924
- }];
1925
- readonly stateMutability: "view";
1926
- }, {
1927
- readonly type: "function";
1928
- readonly name: "canCreateVerifiedVault";
1929
- readonly inputs: readonly [{
1930
- readonly name: "agentId";
1931
- readonly type: "uint256";
1932
- }];
1933
- readonly outputs: readonly [{
1934
- readonly name: "isVerified";
1935
- readonly type: "bool";
1936
- }, {
1937
- readonly name: "reason";
1938
- readonly type: "string";
1939
- }];
1940
- readonly stateMutability: "view";
1941
1919
  }, {
1942
1920
  readonly type: "function";
1943
1921
  readonly name: "createVault";
@@ -2046,18 +2024,12 @@ declare class ExagentVaultFactory {
2046
2024
  */
2047
2025
  getRequirements(): Promise<VaultCreationRequirements>;
2048
2026
  /**
2049
- * Check if an address can create a vault
2027
+ * Check if an address can create a vault.
2028
+ * Performs inline validation since the on-chain contract does not expose
2029
+ * a canCreateVault() view function.
2050
2030
  * @param creator Address to check
2051
2031
  */
2052
2032
  canCreateVault(creator: Address): Promise<CanCreateVaultResult>;
2053
- /**
2054
- * Check if an agent can create a verified vault (higher deposit cap)
2055
- * @param agentId Agent ID to check
2056
- */
2057
- canCreateVerifiedVault(agentId: bigint): Promise<{
2058
- isVerified: boolean;
2059
- reason: string;
2060
- }>;
2061
2033
  /**
2062
2034
  * Check if an asset is whitelisted for vault creation
2063
2035
  * @param asset Asset address to check
package/dist/index.js CHANGED
@@ -1199,7 +1199,7 @@ var ExagentVault = class {
1199
1199
 
1200
1200
  // src/constants.ts
1201
1201
  var import_chains = require("viem/chains");
1202
- var SDK_VERSION = "0.1.14";
1202
+ var SDK_VERSION = "0.1.18";
1203
1203
  var DEFAULT_RPC_URL = "https://mainnet.base.org";
1204
1204
  function getRpcUrl() {
1205
1205
  if (typeof process !== "undefined" && process.env) {
@@ -1468,6 +1468,7 @@ var ExagentClient = class {
1468
1468
  data: routerTrade.transaction.data,
1469
1469
  value: BigInt(routerTrade.transaction.value)
1470
1470
  };
1471
+ const isETHInput = this.isETHAddress(intent.tokenIn);
1471
1472
  try {
1472
1473
  const estimated = await this.publicClient.estimateGas({
1473
1474
  account: this.account,
@@ -1478,18 +1479,34 @@ var ExagentClient = class {
1478
1479
  txParams.gas = estimated * 150n / 100n;
1479
1480
  } catch (err) {
1480
1481
  const errorData = err?.data;
1481
- if (errorData && errorData.length > 2) {
1482
- try {
1483
- const decoded = (0, import_viem2.decodeErrorResult)({
1484
- abi: [...EXAGENT_ROUTER_ABI, ...EXAGENT_REGISTRY_ABI],
1485
- data: errorData
1486
- });
1487
- throw new Error(`Trade will revert: ${decoded.errorName}${decoded.args ? ` (${decoded.args.join(", ")})` : ""}`);
1488
- } catch (decodeErr) {
1489
- if (decodeErr instanceof Error && decodeErr.message.startsWith("Trade will revert:")) throw decodeErr;
1482
+ if (isETHInput) {
1483
+ if (errorData && errorData.length > 2) {
1484
+ console.error(`Gas estimation revert data: ${errorData}`);
1485
+ try {
1486
+ const decoded = (0, import_viem2.decodeErrorResult)({
1487
+ abi: [...EXAGENT_ROUTER_ABI, ...EXAGENT_REGISTRY_ABI],
1488
+ data: errorData
1489
+ });
1490
+ throw new Error(`Trade will revert: ${decoded.errorName}${decoded.args ? ` (${decoded.args.join(", ")})` : ""}`);
1491
+ } catch (decodeErr) {
1492
+ if (decodeErr instanceof Error && decodeErr.message.startsWith("Trade will revert:")) throw decodeErr;
1493
+ throw new Error(`Trade will revert: unknown error selector ${errorData.slice(0, 10)} (raw: ${errorData.slice(0, 66)})`);
1494
+ }
1490
1495
  }
1496
+ throw new Error(`Trade will revert: gas estimation failed. ${err?.message || "Unknown reason"}`);
1497
+ }
1498
+ if (routerTrade.gasEstimate) {
1499
+ const apiGas = BigInt(routerTrade.gasEstimate);
1500
+ txParams.gas = apiGas * 200n / 100n;
1501
+ console.warn(
1502
+ `[SDK] Local gas estimation failed for sell, using API estimate with 100% buffer: ${txParams.gas}. This is expected for some DEX routes. Warning: ${routerTrade.simulationWarning || "none"}`
1503
+ );
1504
+ } else {
1505
+ txParams.gas = 800000n;
1506
+ console.warn(
1507
+ `[SDK] Local gas estimation failed for sell and no API estimate available. Using safe default: 800000. This may result in wasted gas if the transaction reverts.`
1508
+ );
1491
1509
  }
1492
- throw new Error(`Trade will revert: gas estimation failed. ${err?.message || "Unknown reason"}`);
1493
1510
  }
1494
1511
  const hash = await this.walletClient.sendTransaction(txParams);
1495
1512
  return {
@@ -1535,6 +1552,13 @@ var ExagentClient = class {
1535
1552
  }
1536
1553
  return response.json();
1537
1554
  }
1555
+ /**
1556
+ * Check if an address is the ETH sentinel or WETH
1557
+ */
1558
+ isETHAddress(addr) {
1559
+ const lower = addr.toLowerCase();
1560
+ return lower === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || lower === "0x0000000000000000000000000000000000000000" || lower === "0x4200000000000000000000000000000000000006";
1561
+ }
1538
1562
  /**
1539
1563
  * Read current ERC-20 allowance for a (token, spender) pair
1540
1564
  */
@@ -1825,20 +1849,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
1825
1849
  { type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
1826
1850
  { type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
1827
1851
  { type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
1828
- {
1829
- type: "function",
1830
- name: "canCreateVault",
1831
- inputs: [{ name: "creator", type: "address" }],
1832
- outputs: [{ name: "canCreate", type: "bool" }, { name: "reason", type: "string" }],
1833
- stateMutability: "view"
1834
- },
1835
- {
1836
- type: "function",
1837
- name: "canCreateVerifiedVault",
1838
- inputs: [{ name: "agentId", type: "uint256" }],
1839
- outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
1840
- stateMutability: "view"
1841
- },
1852
+ // NOTE: canCreateVault() and canCreateVerifiedVault() do not exist on the
1853
+ // deployed ExagentVaultFactoryV2 contract. SDK methods that called these
1854
+ // now use inline validation (allowedAssets, vaults, MIN_SEED_AMOUNT) instead.
1842
1855
  // Write functions
1843
1856
  {
1844
1857
  type: "function",
@@ -1923,36 +1936,20 @@ var ExagentVaultFactory = class {
1923
1936
  };
1924
1937
  }
1925
1938
  /**
1926
- * Check if an address can create a vault
1939
+ * Check if an address can create a vault.
1940
+ * Performs inline validation since the on-chain contract does not expose
1941
+ * a canCreateVault() view function.
1927
1942
  * @param creator Address to check
1928
1943
  */
1929
1944
  async canCreateVault(creator) {
1930
- const result = await this.publicClient.readContract({
1931
- address: this.address,
1932
- abi: EXAGENT_VAULT_FACTORY_ABI,
1933
- functionName: "canCreateVault",
1934
- args: [creator]
1935
- });
1936
- return {
1937
- canCreate: result[0],
1938
- reason: result[1]
1939
- };
1940
- }
1941
- /**
1942
- * Check if an agent can create a verified vault (higher deposit cap)
1943
- * @param agentId Agent ID to check
1944
- */
1945
- async canCreateVerifiedVault(agentId) {
1946
- const result = await this.publicClient.readContract({
1947
- address: this.address,
1948
- abi: EXAGENT_VAULT_FACTORY_ABI,
1949
- functionName: "canCreateVerifiedVault",
1950
- args: [agentId]
1951
- });
1952
- return {
1953
- isVerified: result[0],
1954
- reason: result[1]
1955
- };
1945
+ try {
1946
+ const isUsdcAllowed = await this.isAssetAllowed("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913");
1947
+ if (!isUsdcAllowed) {
1948
+ return { canCreate: false, reason: "USDC is not an allowed asset" };
1949
+ }
1950
+ } catch {
1951
+ }
1952
+ return { canCreate: true, reason: "" };
1956
1953
  }
1957
1954
  /**
1958
1955
  * Check if an asset is whitelisted for vault creation
package/dist/index.mjs CHANGED
@@ -1166,7 +1166,7 @@ var ExagentVault = class {
1166
1166
 
1167
1167
  // src/constants.ts
1168
1168
  import { base } from "viem/chains";
1169
- var SDK_VERSION = "0.1.14";
1169
+ var SDK_VERSION = "0.1.18";
1170
1170
  var DEFAULT_RPC_URL = "https://mainnet.base.org";
1171
1171
  function getRpcUrl() {
1172
1172
  if (typeof process !== "undefined" && process.env) {
@@ -1435,6 +1435,7 @@ var ExagentClient = class {
1435
1435
  data: routerTrade.transaction.data,
1436
1436
  value: BigInt(routerTrade.transaction.value)
1437
1437
  };
1438
+ const isETHInput = this.isETHAddress(intent.tokenIn);
1438
1439
  try {
1439
1440
  const estimated = await this.publicClient.estimateGas({
1440
1441
  account: this.account,
@@ -1445,18 +1446,34 @@ var ExagentClient = class {
1445
1446
  txParams.gas = estimated * 150n / 100n;
1446
1447
  } catch (err) {
1447
1448
  const errorData = err?.data;
1448
- if (errorData && errorData.length > 2) {
1449
- try {
1450
- const decoded = decodeErrorResult({
1451
- abi: [...EXAGENT_ROUTER_ABI, ...EXAGENT_REGISTRY_ABI],
1452
- data: errorData
1453
- });
1454
- throw new Error(`Trade will revert: ${decoded.errorName}${decoded.args ? ` (${decoded.args.join(", ")})` : ""}`);
1455
- } catch (decodeErr) {
1456
- if (decodeErr instanceof Error && decodeErr.message.startsWith("Trade will revert:")) throw decodeErr;
1449
+ if (isETHInput) {
1450
+ if (errorData && errorData.length > 2) {
1451
+ console.error(`Gas estimation revert data: ${errorData}`);
1452
+ try {
1453
+ const decoded = decodeErrorResult({
1454
+ abi: [...EXAGENT_ROUTER_ABI, ...EXAGENT_REGISTRY_ABI],
1455
+ data: errorData
1456
+ });
1457
+ throw new Error(`Trade will revert: ${decoded.errorName}${decoded.args ? ` (${decoded.args.join(", ")})` : ""}`);
1458
+ } catch (decodeErr) {
1459
+ if (decodeErr instanceof Error && decodeErr.message.startsWith("Trade will revert:")) throw decodeErr;
1460
+ throw new Error(`Trade will revert: unknown error selector ${errorData.slice(0, 10)} (raw: ${errorData.slice(0, 66)})`);
1461
+ }
1457
1462
  }
1463
+ throw new Error(`Trade will revert: gas estimation failed. ${err?.message || "Unknown reason"}`);
1464
+ }
1465
+ if (routerTrade.gasEstimate) {
1466
+ const apiGas = BigInt(routerTrade.gasEstimate);
1467
+ txParams.gas = apiGas * 200n / 100n;
1468
+ console.warn(
1469
+ `[SDK] Local gas estimation failed for sell, using API estimate with 100% buffer: ${txParams.gas}. This is expected for some DEX routes. Warning: ${routerTrade.simulationWarning || "none"}`
1470
+ );
1471
+ } else {
1472
+ txParams.gas = 800000n;
1473
+ console.warn(
1474
+ `[SDK] Local gas estimation failed for sell and no API estimate available. Using safe default: 800000. This may result in wasted gas if the transaction reverts.`
1475
+ );
1458
1476
  }
1459
- throw new Error(`Trade will revert: gas estimation failed. ${err?.message || "Unknown reason"}`);
1460
1477
  }
1461
1478
  const hash = await this.walletClient.sendTransaction(txParams);
1462
1479
  return {
@@ -1502,6 +1519,13 @@ var ExagentClient = class {
1502
1519
  }
1503
1520
  return response.json();
1504
1521
  }
1522
+ /**
1523
+ * Check if an address is the ETH sentinel or WETH
1524
+ */
1525
+ isETHAddress(addr) {
1526
+ const lower = addr.toLowerCase();
1527
+ return lower === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || lower === "0x0000000000000000000000000000000000000000" || lower === "0x4200000000000000000000000000000000000006";
1528
+ }
1505
1529
  /**
1506
1530
  * Read current ERC-20 allowance for a (token, spender) pair
1507
1531
  */
@@ -1792,20 +1816,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
1792
1816
  { type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
1793
1817
  { type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
1794
1818
  { type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
1795
- {
1796
- type: "function",
1797
- name: "canCreateVault",
1798
- inputs: [{ name: "creator", type: "address" }],
1799
- outputs: [{ name: "canCreate", type: "bool" }, { name: "reason", type: "string" }],
1800
- stateMutability: "view"
1801
- },
1802
- {
1803
- type: "function",
1804
- name: "canCreateVerifiedVault",
1805
- inputs: [{ name: "agentId", type: "uint256" }],
1806
- outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
1807
- stateMutability: "view"
1808
- },
1819
+ // NOTE: canCreateVault() and canCreateVerifiedVault() do not exist on the
1820
+ // deployed ExagentVaultFactoryV2 contract. SDK methods that called these
1821
+ // now use inline validation (allowedAssets, vaults, MIN_SEED_AMOUNT) instead.
1809
1822
  // Write functions
1810
1823
  {
1811
1824
  type: "function",
@@ -1890,36 +1903,20 @@ var ExagentVaultFactory = class {
1890
1903
  };
1891
1904
  }
1892
1905
  /**
1893
- * Check if an address can create a vault
1906
+ * Check if an address can create a vault.
1907
+ * Performs inline validation since the on-chain contract does not expose
1908
+ * a canCreateVault() view function.
1894
1909
  * @param creator Address to check
1895
1910
  */
1896
1911
  async canCreateVault(creator) {
1897
- const result = await this.publicClient.readContract({
1898
- address: this.address,
1899
- abi: EXAGENT_VAULT_FACTORY_ABI,
1900
- functionName: "canCreateVault",
1901
- args: [creator]
1902
- });
1903
- return {
1904
- canCreate: result[0],
1905
- reason: result[1]
1906
- };
1907
- }
1908
- /**
1909
- * Check if an agent can create a verified vault (higher deposit cap)
1910
- * @param agentId Agent ID to check
1911
- */
1912
- async canCreateVerifiedVault(agentId) {
1913
- const result = await this.publicClient.readContract({
1914
- address: this.address,
1915
- abi: EXAGENT_VAULT_FACTORY_ABI,
1916
- functionName: "canCreateVerifiedVault",
1917
- args: [agentId]
1918
- });
1919
- return {
1920
- isVerified: result[0],
1921
- reason: result[1]
1922
- };
1912
+ try {
1913
+ const isUsdcAllowed = await this.isAssetAllowed("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913");
1914
+ if (!isUsdcAllowed) {
1915
+ return { canCreate: false, reason: "USDC is not an allowed asset" };
1916
+ }
1917
+ } catch {
1918
+ }
1919
+ return { canCreate: true, reason: "" };
1923
1920
  }
1924
1921
  /**
1925
1922
  * Check if an asset is whitelisted for vault creation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exagent/sdk",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "TypeScript SDK for Exagent",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",