@spectratools/aborean-cli 0.7.0 → 0.9.0

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.
Files changed (2) hide show
  1. package/dist/cli.js +913 -422
  2. package/package.json +3 -2
package/dist/cli.js CHANGED
@@ -5,12 +5,12 @@ import { readFileSync } from "fs";
5
5
  import { dirname, resolve } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { checksumAddress as checksumAddress6 } from "@spectratools/cli-shared";
8
- import { Cli as Cli8, z as z8 } from "incur";
8
+ import { Cli as Cli8, z as z9 } from "incur";
9
9
  import { formatUnits as formatUnits4 } from "viem";
10
10
 
11
11
  // src/commands/cl.ts
12
- import { checksumAddress, isAddress } from "@spectratools/cli-shared";
13
- import { Cli, z } from "incur";
12
+ import { checksumAddress as checksumAddress2, isAddress } from "@spectratools/cli-shared";
13
+ import { Cli, z as z2 } from "incur";
14
14
  import { formatUnits, parseUnits } from "viem";
15
15
 
16
16
  // src/contracts/abis/CLFactory.abi.json
@@ -560,6 +560,47 @@ var RewardsDistributor_abi_default = [
560
560
  }
561
561
  ];
562
562
 
563
+ // src/contracts/abis/SwapRouter.abi.json
564
+ var SwapRouter_abi_default = [
565
+ {
566
+ type: "function",
567
+ name: "exactInputSingle",
568
+ inputs: [
569
+ {
570
+ name: "params",
571
+ type: "tuple",
572
+ internalType: "struct ISwapRouter.ExactInputSingleParams",
573
+ components: [
574
+ { name: "tokenIn", type: "address", internalType: "address" },
575
+ { name: "tokenOut", type: "address", internalType: "address" },
576
+ { name: "tickSpacing", type: "int24", internalType: "int24" },
577
+ { name: "recipient", type: "address", internalType: "address" },
578
+ { name: "deadline", type: "uint256", internalType: "uint256" },
579
+ { name: "amountIn", type: "uint256", internalType: "uint256" },
580
+ { name: "amountOutMinimum", type: "uint256", internalType: "uint256" },
581
+ { name: "sqrtPriceLimitX96", type: "uint160", internalType: "uint160" }
582
+ ]
583
+ }
584
+ ],
585
+ outputs: [{ name: "amountOut", type: "uint256", internalType: "uint256" }],
586
+ stateMutability: "payable"
587
+ },
588
+ {
589
+ type: "function",
590
+ name: "factory",
591
+ inputs: [],
592
+ outputs: [{ name: "", type: "address", internalType: "address" }],
593
+ stateMutability: "view"
594
+ },
595
+ {
596
+ type: "function",
597
+ name: "WETH9",
598
+ inputs: [],
599
+ outputs: [{ name: "", type: "address", internalType: "address" }],
600
+ stateMutability: "view"
601
+ }
602
+ ];
603
+
563
604
  // src/contracts/abis/V2Pool.abi.json
564
605
  var V2Pool_abi_default = [
565
606
  {
@@ -947,6 +988,7 @@ var nonfungiblePositionManagerAbi = NonfungiblePositionManager_abi_default;
947
988
  var poolFactoryAbi = PoolFactory_abi_default;
948
989
  var quoterV2Abi = QuoterV2_abi_default;
949
990
  var rewardsDistributorAbi = RewardsDistributor_abi_default;
991
+ var swapRouterAbi = SwapRouter_abi_default;
950
992
  var v2PoolAbi = V2Pool_abi_default;
951
993
  var v2RouterAbi = V2Router_abi_default;
952
994
  var voterAbi = Voter_abi_default;
@@ -1032,7 +1074,12 @@ var ABOREAN_ADDRESSES = {
1032
1074
  };
1033
1075
 
1034
1076
  // src/contracts/client.ts
1035
- import { http, createPublicClient, defineChain } from "viem";
1077
+ import {
1078
+ http,
1079
+ createPublicClient,
1080
+ createWalletClient,
1081
+ defineChain
1082
+ } from "viem";
1036
1083
  var abstractMainnet = defineChain({
1037
1084
  id: 2741,
1038
1085
  name: "Abstract Mainnet",
@@ -1053,63 +1100,174 @@ function createAboreanPublicClient(rpcUrl) {
1053
1100
  transport: http(rpcUrl ?? process.env.ABSTRACT_RPC_URL ?? "https://api.mainnet.abs.xyz")
1054
1101
  });
1055
1102
  }
1103
+ function createAboreanWalletClient(account, rpcUrl) {
1104
+ return createWalletClient({
1105
+ account,
1106
+ chain: abstractMainnet,
1107
+ transport: http(rpcUrl ?? process.env.ABSTRACT_RPC_URL ?? "https://api.mainnet.abs.xyz")
1108
+ });
1109
+ }
1110
+
1111
+ // src/commands/_write-utils.ts
1112
+ import {
1113
+ createPrivateKeySigner,
1114
+ executeTx
1115
+ } from "@spectratools/tx-shared";
1116
+ import { z } from "incur";
1117
+
1118
+ // src/commands/_common.ts
1119
+ import { checksumAddress, weiToEth } from "@spectratools/cli-shared";
1120
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1121
+ function toChecksum(address) {
1122
+ try {
1123
+ return checksumAddress(address);
1124
+ } catch {
1125
+ return address;
1126
+ }
1127
+ }
1128
+ function asNum(value) {
1129
+ return Number(value);
1130
+ }
1131
+ function relTime(unixSeconds) {
1132
+ const ts = typeof unixSeconds === "bigint" ? Number(unixSeconds) : unixSeconds;
1133
+ if (!Number.isFinite(ts) || ts <= 0) return "n/a";
1134
+ const delta = ts - Math.floor(Date.now() / 1e3);
1135
+ const abs = Math.abs(delta);
1136
+ const hours = Math.floor(abs / 3600);
1137
+ const minutes = Math.floor(abs % 3600 / 60);
1138
+ const label = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
1139
+ return delta >= 0 ? `in ${label}` : `${label} ago`;
1140
+ }
1141
+ function clampPositive(seconds) {
1142
+ return seconds > 0 ? seconds : 0;
1143
+ }
1144
+ function jsonSafe(value) {
1145
+ if (typeof value === "bigint") return value.toString();
1146
+ if (Array.isArray(value)) return value.map((item) => jsonSafe(item));
1147
+ if (value && typeof value === "object") {
1148
+ return Object.fromEntries(
1149
+ Object.entries(value).map(([key, entry]) => [
1150
+ key,
1151
+ jsonSafe(entry)
1152
+ ])
1153
+ );
1154
+ }
1155
+ return value;
1156
+ }
1157
+
1158
+ // src/commands/_write-utils.ts
1159
+ var PRIVATE_KEY_MISSING_MESSAGE = "Missing PRIVATE_KEY env var. Set PRIVATE_KEY to a 0x-prefixed 32-byte hex private key.";
1160
+ var writeEnv = z.object({
1161
+ ABSTRACT_RPC_URL: z.string().optional().describe("Abstract RPC URL override"),
1162
+ PRIVATE_KEY: z.string().min(1, PRIVATE_KEY_MISSING_MESSAGE).describe("Private key (0x-prefixed 32-byte hex) for signing transactions")
1163
+ });
1164
+ var writeOptions = z.object({
1165
+ "dry-run": z.boolean().default(false).describe("Simulate the transaction without broadcasting"),
1166
+ "gas-limit": z.string().optional().describe("Gas limit override (in gas units)"),
1167
+ "max-fee": z.string().optional().describe("Max fee per gas override in wei (EIP-1559)"),
1168
+ nonce: z.number().optional().describe("Nonce override")
1169
+ });
1170
+ function resolveAccount(env8) {
1171
+ const privateKey = env8.PRIVATE_KEY?.trim();
1172
+ if (!privateKey) {
1173
+ throw new Error(PRIVATE_KEY_MISSING_MESSAGE);
1174
+ }
1175
+ const signer = createPrivateKeySigner(privateKey);
1176
+ return signer.account;
1177
+ }
1178
+ function formatTxResult(result) {
1179
+ if (result.status === "dry-run") {
1180
+ return {
1181
+ dryRun: true,
1182
+ estimatedGas: result.estimatedGas.toString(),
1183
+ simulationResult: jsonSafe(result.simulationResult),
1184
+ ...result.privyPolicy !== void 0 ? { privyPolicy: jsonSafe(result.privyPolicy) } : {}
1185
+ };
1186
+ }
1187
+ return {
1188
+ txHash: result.hash,
1189
+ blockNumber: Number(result.blockNumber),
1190
+ gasUsed: result.gasUsed.toString()
1191
+ };
1192
+ }
1193
+ async function aboreanWriteTx(opts) {
1194
+ const { env: env8, options, address, abi, functionName, args, value } = opts;
1195
+ const account = resolveAccount(env8);
1196
+ const publicClient = createAboreanPublicClient(env8.ABSTRACT_RPC_URL);
1197
+ const walletClient = createAboreanWalletClient(account, env8.ABSTRACT_RPC_URL);
1198
+ const result = await executeTx({
1199
+ publicClient,
1200
+ walletClient,
1201
+ account,
1202
+ address,
1203
+ abi,
1204
+ functionName,
1205
+ ...args !== void 0 ? { args } : {},
1206
+ ...value !== void 0 ? { value } : {},
1207
+ dryRun: options["dry-run"],
1208
+ ...options["gas-limit"] ? { gasLimit: BigInt(options["gas-limit"]) } : {},
1209
+ ...options["max-fee"] ? { maxFeePerGas: BigInt(options["max-fee"]) } : {},
1210
+ ...options.nonce !== void 0 ? { nonce: options.nonce } : {}
1211
+ });
1212
+ return formatTxResult(result);
1213
+ }
1056
1214
 
1057
1215
  // src/commands/cl.ts
1058
1216
  var Q96 = 2n ** 96n;
1059
1217
  var MULTICALL_BATCH_SIZE = 100;
1060
- var env = z.object({
1061
- ABSTRACT_RPC_URL: z.string().optional().describe("Abstract RPC URL override")
1218
+ var env = z2.object({
1219
+ ABSTRACT_RPC_URL: z2.string().optional().describe("Abstract RPC URL override")
1062
1220
  });
1063
- var tokenSchema = z.object({
1064
- address: z.string(),
1065
- symbol: z.string(),
1066
- decimals: z.number()
1221
+ var tokenSchema = z2.object({
1222
+ address: z2.string(),
1223
+ symbol: z2.string(),
1224
+ decimals: z2.number()
1067
1225
  });
1068
- var poolRowSchema = z.object({
1069
- pool: z.string(),
1070
- pair: z.string(),
1226
+ var poolRowSchema = z2.object({
1227
+ pool: z2.string(),
1228
+ pair: z2.string(),
1071
1229
  token0: tokenSchema,
1072
1230
  token1: tokenSchema,
1073
- fee: z.number(),
1074
- feePercent: z.number(),
1075
- tickSpacing: z.number(),
1076
- liquidity: z.string(),
1077
- currentTick: z.number(),
1078
- sqrtPriceX96: z.string(),
1079
- activeLiquidityEstimate: z.object({
1080
- token0: z.string(),
1081
- token1: z.string(),
1082
- totalInToken0: z.number().nullable(),
1083
- totalInToken1: z.number().nullable()
1231
+ fee: z2.number(),
1232
+ feePercent: z2.number(),
1233
+ tickSpacing: z2.number(),
1234
+ liquidity: z2.string(),
1235
+ currentTick: z2.number(),
1236
+ sqrtPriceX96: z2.string(),
1237
+ activeLiquidityEstimate: z2.object({
1238
+ token0: z2.string(),
1239
+ token1: z2.string(),
1240
+ totalInToken0: z2.number().nullable(),
1241
+ totalInToken1: z2.number().nullable()
1084
1242
  }),
1085
- price: z.object({
1086
- token1PerToken0: z.number().nullable(),
1087
- token0PerToken1: z.number().nullable()
1243
+ price: z2.object({
1244
+ token1PerToken0: z2.number().nullable(),
1245
+ token0PerToken1: z2.number().nullable()
1088
1246
  })
1089
1247
  });
1090
- var quoteOutputSchema = z.object({
1091
- pool: z.string(),
1092
- selectedFee: z.number(),
1093
- selectedTickSpacing: z.number(),
1248
+ var quoteOutputSchema = z2.object({
1249
+ pool: z2.string(),
1250
+ selectedFee: z2.number(),
1251
+ selectedTickSpacing: z2.number(),
1094
1252
  tokenIn: tokenSchema,
1095
1253
  tokenOut: tokenSchema,
1096
- amountIn: z.object({
1097
- raw: z.string(),
1098
- decimal: z.string()
1254
+ amountIn: z2.object({
1255
+ raw: z2.string(),
1256
+ decimal: z2.string()
1099
1257
  }),
1100
- amountOut: z.object({
1101
- raw: z.string(),
1102
- decimal: z.string()
1258
+ amountOut: z2.object({
1259
+ raw: z2.string(),
1260
+ decimal: z2.string()
1103
1261
  }),
1104
- execution: z.object({
1105
- sqrtPriceX96After: z.string(),
1106
- initializedTicksCrossed: z.number(),
1107
- gasEstimate: z.string()
1262
+ execution: z2.object({
1263
+ sqrtPriceX96After: z2.string(),
1264
+ initializedTicksCrossed: z2.number(),
1265
+ gasEstimate: z2.string()
1108
1266
  }),
1109
- prices: z.object({
1110
- poolMidPriceOutPerIn: z.number().nullable(),
1111
- quotePriceOutPerIn: z.number().nullable(),
1112
- priceImpactPct: z.number().nullable()
1267
+ prices: z2.object({
1268
+ poolMidPriceOutPerIn: z2.number().nullable(),
1269
+ quotePriceOutPerIn: z2.number().nullable(),
1270
+ priceImpactPct: z2.number().nullable()
1113
1271
  })
1114
1272
  });
1115
1273
  var erc20MetadataAbi = [
@@ -1137,7 +1295,7 @@ function finiteOrNull(value) {
1137
1295
  function toTokenMetaFallback(address) {
1138
1296
  return {
1139
1297
  address,
1140
- symbol: shortAddress(checksumAddress(address)),
1298
+ symbol: shortAddress(checksumAddress2(address)),
1141
1299
  decimals: 18
1142
1300
  };
1143
1301
  }
@@ -1232,7 +1390,7 @@ async function readTokenMetadata(client, tokenAddresses) {
1232
1390
  const symbol = symbolResult && symbolResult.status === "success" && typeof symbolResult.result === "string" ? symbolResult.result : fallback.symbol;
1233
1391
  const decimals = decimalsResult && decimalsResult.status === "success" && typeof decimalsResult.result === "number" ? decimalsResult.result : fallback.decimals;
1234
1392
  out.set(address, {
1235
- address: checksumAddress(address),
1393
+ address: checksumAddress2(address),
1236
1394
  symbol,
1237
1395
  decimals
1238
1396
  });
@@ -1316,7 +1474,7 @@ function toPoolRow(pool, tokenMeta) {
1316
1474
  prices
1317
1475
  );
1318
1476
  return {
1319
- pool: checksumAddress(pool.pool),
1477
+ pool: checksumAddress2(pool.pool),
1320
1478
  pair: `${token0.symbol}/${token1.symbol}`,
1321
1479
  token0,
1322
1480
  token1,
@@ -1339,9 +1497,9 @@ var cl = Cli.create("cl", {
1339
1497
  cl.command("pools", {
1340
1498
  description: "List Slipstream pools with current state, prices, and active liquidity estimate.",
1341
1499
  env,
1342
- output: z.object({
1343
- count: z.number(),
1344
- pools: z.array(poolRowSchema)
1500
+ output: z2.object({
1501
+ count: z2.number(),
1502
+ pools: z2.array(poolRowSchema)
1345
1503
  }),
1346
1504
  async run(c) {
1347
1505
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -1382,11 +1540,11 @@ cl.command("pools", {
1382
1540
  });
1383
1541
  cl.command("pool", {
1384
1542
  description: "Get detailed state for a Slipstream pool address.",
1385
- args: z.object({
1386
- pool: z.string().describe("Pool address")
1543
+ args: z2.object({
1544
+ pool: z2.string().describe("Pool address")
1387
1545
  }),
1388
1546
  env,
1389
- output: z.object({
1547
+ output: z2.object({
1390
1548
  pool: poolRowSchema
1391
1549
  }),
1392
1550
  async run(c) {
@@ -1397,7 +1555,7 @@ cl.command("pool", {
1397
1555
  });
1398
1556
  }
1399
1557
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1400
- const checksummedPool = checksumAddress(c.args.pool);
1558
+ const checksummedPool = checksumAddress2(c.args.pool);
1401
1559
  const [poolState] = await readPoolStates(client, [checksummedPool]);
1402
1560
  const tokenMeta = await readTokenMetadata(client, [poolState.token0, poolState.token1]);
1403
1561
  const row = toPoolRow(poolState, tokenMeta);
@@ -1431,25 +1589,25 @@ cl.command("pool", {
1431
1589
  });
1432
1590
  cl.command("positions", {
1433
1591
  description: "List concentrated liquidity NFT positions for an owner.",
1434
- args: z.object({
1435
- owner: z.string().describe("Owner wallet address")
1592
+ args: z2.object({
1593
+ owner: z2.string().describe("Owner wallet address")
1436
1594
  }),
1437
1595
  env,
1438
- output: z.object({
1439
- owner: z.string(),
1440
- count: z.number(),
1441
- positions: z.array(
1442
- z.object({
1443
- tokenId: z.string(),
1444
- pair: z.string(),
1596
+ output: z2.object({
1597
+ owner: z2.string(),
1598
+ count: z2.number(),
1599
+ positions: z2.array(
1600
+ z2.object({
1601
+ tokenId: z2.string(),
1602
+ pair: z2.string(),
1445
1603
  token0: tokenSchema,
1446
1604
  token1: tokenSchema,
1447
- tickSpacing: z.number(),
1448
- tickLower: z.number(),
1449
- tickUpper: z.number(),
1450
- liquidity: z.string(),
1451
- tokensOwed0: z.object({ raw: z.string(), decimal: z.string() }),
1452
- tokensOwed1: z.object({ raw: z.string(), decimal: z.string() })
1605
+ tickSpacing: z2.number(),
1606
+ tickLower: z2.number(),
1607
+ tickUpper: z2.number(),
1608
+ liquidity: z2.string(),
1609
+ tokensOwed0: z2.object({ raw: z2.string(), decimal: z2.string() }),
1610
+ tokensOwed1: z2.object({ raw: z2.string(), decimal: z2.string() })
1453
1611
  })
1454
1612
  )
1455
1613
  }),
@@ -1461,7 +1619,7 @@ cl.command("positions", {
1461
1619
  });
1462
1620
  }
1463
1621
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1464
- const owner = checksumAddress(c.args.owner);
1622
+ const owner = checksumAddress2(c.args.owner);
1465
1623
  const balance = await client.readContract({
1466
1624
  abi: nonfungiblePositionManagerAbi,
1467
1625
  address: ABOREAN_CL_ADDRESSES.nonfungiblePositionManager,
@@ -1545,13 +1703,13 @@ cl.command("positions", {
1545
1703
  });
1546
1704
  cl.command("quote", {
1547
1705
  description: "Quote a single-hop Slipstream swap via QuoterV2.",
1548
- args: z.object({
1549
- tokenIn: z.string().describe("Input token address"),
1550
- tokenOut: z.string().describe("Output token address"),
1551
- amountIn: z.string().describe("Input amount in human-readable decimal units")
1706
+ args: z2.object({
1707
+ tokenIn: z2.string().describe("Input token address"),
1708
+ tokenOut: z2.string().describe("Output token address"),
1709
+ amountIn: z2.string().describe("Input amount in human-readable decimal units")
1552
1710
  }),
1553
- options: z.object({
1554
- fee: z.coerce.number().int().positive().optional().describe("Optional fee tier filter")
1711
+ options: z2.object({
1712
+ fee: z2.coerce.number().int().positive().optional().describe("Optional fee tier filter")
1555
1713
  }),
1556
1714
  env,
1557
1715
  output: quoteOutputSchema,
@@ -1564,8 +1722,8 @@ cl.command("quote", {
1564
1722
  });
1565
1723
  }
1566
1724
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1567
- const inAddress = checksumAddress(tokenIn);
1568
- const outAddress = checksumAddress(tokenOut);
1725
+ const inAddress = checksumAddress2(tokenIn);
1726
+ const outAddress = checksumAddress2(tokenOut);
1569
1727
  const allPools = await listPoolAddresses(client);
1570
1728
  const poolStates = await readPoolStates(client, allPools);
1571
1729
  const pairPools = poolStates.filter((pool) => {
@@ -1632,7 +1790,7 @@ cl.command("quote", {
1632
1790
  const priceImpactPct = quotePriceOutPerIn === null || poolMidPriceOutPerIn === null || poolMidPriceOutPerIn === 0 ? null : finiteOrNull((poolMidPriceOutPerIn - quotePriceOutPerIn) / poolMidPriceOutPerIn * 100);
1633
1791
  return c.ok(
1634
1792
  {
1635
- pool: checksumAddress(selectedPool.pool),
1793
+ pool: checksumAddress2(selectedPool.pool),
1636
1794
  selectedFee: selectedPool.fee,
1637
1795
  selectedTickSpacing: selectedPool.tickSpacing,
1638
1796
  tokenIn: inMeta,
@@ -1662,7 +1820,7 @@ cl.command("quote", {
1662
1820
  commands: [
1663
1821
  {
1664
1822
  command: "cl pool",
1665
- args: { pool: checksumAddress(selectedPool.pool) },
1823
+ args: { pool: checksumAddress2(selectedPool.pool) },
1666
1824
  description: "Inspect the pool used for this quote"
1667
1825
  },
1668
1826
  {
@@ -1680,40 +1838,164 @@ cl.command("quote", {
1680
1838
  );
1681
1839
  }
1682
1840
  });
1683
-
1684
- // src/commands/gauges.ts
1685
- import { Cli as Cli2, z as z2 } from "incur";
1686
-
1687
- // src/commands/_common.ts
1688
- import { checksumAddress as checksumAddress2, weiToEth } from "@spectratools/cli-shared";
1689
- var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1690
- function toChecksum(address) {
1691
- try {
1692
- return checksumAddress2(address);
1693
- } catch {
1694
- return address;
1841
+ var DEFAULT_SLIPPAGE_PERCENT = 0.5;
1842
+ var DEFAULT_DEADLINE_SECONDS = 300;
1843
+ var swapOutputSchema = z2.object({
1844
+ pool: z2.string(),
1845
+ tokenIn: tokenSchema,
1846
+ tokenOut: tokenSchema,
1847
+ amountIn: z2.object({ raw: z2.string(), decimal: z2.string() }),
1848
+ quotedAmountOut: z2.object({ raw: z2.string(), decimal: z2.string() }),
1849
+ amountOutMinimum: z2.object({ raw: z2.string(), decimal: z2.string() }),
1850
+ slippagePercent: z2.number(),
1851
+ deadlineSeconds: z2.number(),
1852
+ tx: z2.union([
1853
+ z2.object({
1854
+ txHash: z2.string(),
1855
+ blockNumber: z2.number(),
1856
+ gasUsed: z2.string()
1857
+ }),
1858
+ z2.object({
1859
+ dryRun: z2.literal(true),
1860
+ estimatedGas: z2.string(),
1861
+ simulationResult: z2.unknown()
1862
+ })
1863
+ ])
1864
+ });
1865
+ cl.command("swap", {
1866
+ description: "Execute a single-hop Slipstream swap via the CL SwapRouter.",
1867
+ options: z2.object({
1868
+ "token-in": z2.string().describe("Input token address"),
1869
+ "token-out": z2.string().describe("Output token address"),
1870
+ "amount-in": z2.string().describe("Input amount in wei"),
1871
+ slippage: z2.coerce.number().default(DEFAULT_SLIPPAGE_PERCENT).describe("Slippage tolerance in percent (default: 0.5)"),
1872
+ deadline: z2.coerce.number().int().default(DEFAULT_DEADLINE_SECONDS).describe("Transaction deadline in seconds from now (default: 300)"),
1873
+ ...writeOptions.shape
1874
+ }),
1875
+ env: writeEnv,
1876
+ output: swapOutputSchema,
1877
+ async run(c) {
1878
+ const tokenIn = c.options["token-in"];
1879
+ const tokenOut = c.options["token-out"];
1880
+ const amountInWei = c.options["amount-in"];
1881
+ const slippage = c.options.slippage;
1882
+ const deadlineSeconds = c.options.deadline;
1883
+ if (!isAddress(tokenIn) || !isAddress(tokenOut)) {
1884
+ return c.error({
1885
+ code: "INVALID_ADDRESS",
1886
+ message: "token-in and token-out must both be valid 0x-prefixed 20-byte addresses."
1887
+ });
1888
+ }
1889
+ const inAddress = checksumAddress2(tokenIn);
1890
+ const outAddress = checksumAddress2(tokenOut);
1891
+ let amountInRaw;
1892
+ try {
1893
+ amountInRaw = BigInt(amountInWei);
1894
+ } catch {
1895
+ return c.error({
1896
+ code: "INVALID_AMOUNT",
1897
+ message: `Invalid amount-in: "${amountInWei}". Provide a valid integer in wei.`
1898
+ });
1899
+ }
1900
+ if (amountInRaw <= 0n) {
1901
+ return c.error({
1902
+ code: "INVALID_AMOUNT",
1903
+ message: "amount-in must be a positive integer."
1904
+ });
1905
+ }
1906
+ if (slippage < 0 || slippage > 100) {
1907
+ return c.error({
1908
+ code: "INVALID_SLIPPAGE",
1909
+ message: `Slippage must be between 0 and 100. Got: ${slippage}`
1910
+ });
1911
+ }
1912
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
1913
+ const allPools = await listPoolAddresses(client);
1914
+ const poolStates = await readPoolStates(client, allPools);
1915
+ const pairPools = poolStates.filter((pool) => {
1916
+ const a = normalizeAddress(pool.token0);
1917
+ const b = normalizeAddress(pool.token1);
1918
+ const tokenInNorm = normalizeAddress(inAddress);
1919
+ const tokenOutNorm = normalizeAddress(outAddress);
1920
+ return a === tokenInNorm && b === tokenOutNorm || a === tokenOutNorm && b === tokenInNorm;
1921
+ });
1922
+ if (pairPools.length === 0) {
1923
+ return c.error({
1924
+ code: "POOL_NOT_FOUND",
1925
+ message: `No Slipstream pool found for pair ${inAddress}/${outAddress}.`
1926
+ });
1927
+ }
1928
+ const selectedPool = [...pairPools].sort((a, b) => {
1929
+ if (a.liquidity === b.liquidity) return 0;
1930
+ return a.liquidity > b.liquidity ? -1 : 1;
1931
+ })[0];
1932
+ const tokenMeta = await readTokenMetadata(client, [inAddress, outAddress]);
1933
+ const inMeta = tokenMeta.get(inAddress) ?? toTokenMetaFallback(inAddress);
1934
+ const outMeta = tokenMeta.get(outAddress) ?? toTokenMetaFallback(outAddress);
1935
+ const quote = await client.readContract({
1936
+ abi: quoterV2Abi,
1937
+ address: ABOREAN_CL_ADDRESSES.quoterV2,
1938
+ functionName: "quoteExactInputSingle",
1939
+ args: [
1940
+ {
1941
+ tokenIn: inAddress,
1942
+ tokenOut: outAddress,
1943
+ amountIn: amountInRaw,
1944
+ tickSpacing: selectedPool.tickSpacing,
1945
+ sqrtPriceLimitX96: 0n
1946
+ }
1947
+ ]
1948
+ });
1949
+ const quotedAmountOut = quote[0];
1950
+ const slippageBps = BigInt(Math.round(slippage * 100));
1951
+ const amountOutMinimum = quotedAmountOut - quotedAmountOut * slippageBps / 10000n;
1952
+ const account = resolveAccount(c.env);
1953
+ const deadlineTimestamp = BigInt(Math.floor(Date.now() / 1e3) + deadlineSeconds);
1954
+ const txResult = await aboreanWriteTx({
1955
+ env: c.env,
1956
+ options: {
1957
+ "dry-run": c.options["dry-run"],
1958
+ "gas-limit": c.options["gas-limit"],
1959
+ "max-fee": c.options["max-fee"],
1960
+ nonce: c.options.nonce
1961
+ },
1962
+ address: ABOREAN_CL_ADDRESSES.swapRouter,
1963
+ abi: swapRouterAbi,
1964
+ functionName: "exactInputSingle",
1965
+ args: [
1966
+ {
1967
+ tokenIn: inAddress,
1968
+ tokenOut: outAddress,
1969
+ tickSpacing: selectedPool.tickSpacing,
1970
+ recipient: account.address,
1971
+ deadline: deadlineTimestamp,
1972
+ amountIn: amountInRaw,
1973
+ amountOutMinimum,
1974
+ sqrtPriceLimitX96: 0n
1975
+ }
1976
+ ]
1977
+ });
1978
+ const amountInDecimal = formatUnits(amountInRaw, inMeta.decimals);
1979
+ const quotedOutDecimal = formatUnits(quotedAmountOut, outMeta.decimals);
1980
+ const minOutDecimal = formatUnits(amountOutMinimum, outMeta.decimals);
1981
+ return c.ok({
1982
+ pool: checksumAddress2(selectedPool.pool),
1983
+ tokenIn: inMeta,
1984
+ tokenOut: outMeta,
1985
+ amountIn: { raw: amountInRaw.toString(), decimal: amountInDecimal },
1986
+ quotedAmountOut: { raw: quotedAmountOut.toString(), decimal: quotedOutDecimal },
1987
+ amountOutMinimum: { raw: amountOutMinimum.toString(), decimal: minOutDecimal },
1988
+ slippagePercent: slippage,
1989
+ deadlineSeconds,
1990
+ tx: txResult
1991
+ });
1695
1992
  }
1696
- }
1697
- function asNum(value) {
1698
- return Number(value);
1699
- }
1700
- function relTime(unixSeconds) {
1701
- const ts = typeof unixSeconds === "bigint" ? Number(unixSeconds) : unixSeconds;
1702
- if (!Number.isFinite(ts) || ts <= 0) return "n/a";
1703
- const delta = ts - Math.floor(Date.now() / 1e3);
1704
- const abs = Math.abs(delta);
1705
- const hours = Math.floor(abs / 3600);
1706
- const minutes = Math.floor(abs % 3600 / 60);
1707
- const label = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
1708
- return delta >= 0 ? `in ${label}` : `${label} ago`;
1709
- }
1710
- function clampPositive(seconds) {
1711
- return seconds > 0 ? seconds : 0;
1712
- }
1993
+ });
1713
1994
 
1714
1995
  // src/commands/gauges.ts
1715
- var env2 = z2.object({
1716
- ABSTRACT_RPC_URL: z2.string().optional().describe("Abstract RPC URL override")
1996
+ import { Cli as Cli2, z as z3 } from "incur";
1997
+ var env2 = z3.object({
1998
+ ABSTRACT_RPC_URL: z3.string().optional().describe("Abstract RPC URL override")
1717
1999
  });
1718
2000
  async function discoverGaugePools(client) {
1719
2001
  const [v2PoolCount, clPoolCount] = await Promise.all([
@@ -1769,20 +2051,20 @@ var gauges = Cli2.create("gauges", {
1769
2051
  gauges.command("list", {
1770
2052
  description: "List active gauges with pool, emissions, and staking stats.",
1771
2053
  env: env2,
1772
- output: z2.object({
1773
- gauges: z2.array(
1774
- z2.object({
1775
- pool: z2.string(),
1776
- gauge: z2.string(),
1777
- rewardToken: z2.string(),
1778
- rewardRate: z2.string(),
1779
- totalStaked: z2.string(),
1780
- claimableEmissions: z2.string(),
1781
- periodFinish: z2.number(),
1782
- periodFinishRelative: z2.string()
2054
+ output: z3.object({
2055
+ gauges: z3.array(
2056
+ z3.object({
2057
+ pool: z3.string(),
2058
+ gauge: z3.string(),
2059
+ rewardToken: z3.string(),
2060
+ rewardRate: z3.string(),
2061
+ totalStaked: z3.string(),
2062
+ claimableEmissions: z3.string(),
2063
+ periodFinish: z3.number(),
2064
+ periodFinishRelative: z3.string()
1783
2065
  })
1784
2066
  ),
1785
- count: z2.number()
2067
+ count: z3.number()
1786
2068
  }),
1787
2069
  examples: [{ description: "List all active gauges and current emissions state" }],
1788
2070
  async run(c) {
@@ -1863,27 +2145,27 @@ gauges.command("list", {
1863
2145
  });
1864
2146
  gauges.command("info", {
1865
2147
  description: "Get detailed state for one gauge address.",
1866
- args: z2.object({
1867
- gauge: z2.string().describe("Gauge contract address")
2148
+ args: z3.object({
2149
+ gauge: z3.string().describe("Gauge contract address")
1868
2150
  }),
1869
2151
  env: env2,
1870
- output: z2.object({
1871
- gauge: z2.string(),
1872
- pool: z2.string(),
1873
- isAlive: z2.boolean(),
1874
- stakingToken: z2.string(),
1875
- rewardToken: z2.string(),
1876
- totalStaked: z2.string(),
1877
- rewardRate: z2.string(),
1878
- rewardPerTokenStored: z2.string(),
1879
- fees0: z2.string(),
1880
- fees1: z2.string(),
1881
- left: z2.string(),
1882
- periodFinish: z2.number(),
1883
- periodFinishRelative: z2.string(),
1884
- lastUpdateTime: z2.number(),
1885
- bribeContract: z2.string(),
1886
- feeContract: z2.string()
2152
+ output: z3.object({
2153
+ gauge: z3.string(),
2154
+ pool: z3.string(),
2155
+ isAlive: z3.boolean(),
2156
+ stakingToken: z3.string(),
2157
+ rewardToken: z3.string(),
2158
+ totalStaked: z3.string(),
2159
+ rewardRate: z3.string(),
2160
+ rewardPerTokenStored: z3.string(),
2161
+ fees0: z3.string(),
2162
+ fees1: z3.string(),
2163
+ left: z3.string(),
2164
+ periodFinish: z3.number(),
2165
+ periodFinishRelative: z3.string(),
2166
+ lastUpdateTime: z3.number(),
2167
+ bribeContract: z3.string(),
2168
+ feeContract: z3.string()
1887
2169
  }),
1888
2170
  examples: [
1889
2171
  {
@@ -2029,22 +2311,22 @@ gauges.command("info", {
2029
2311
  });
2030
2312
  gauges.command("staked", {
2031
2313
  description: "Show one address staking positions across all gauges.",
2032
- args: z2.object({
2033
- address: z2.string().describe("Wallet address to inspect")
2314
+ args: z3.object({
2315
+ address: z3.string().describe("Wallet address to inspect")
2034
2316
  }),
2035
2317
  env: env2,
2036
- output: z2.object({
2037
- address: z2.string(),
2038
- positions: z2.array(
2039
- z2.object({
2040
- pool: z2.string(),
2041
- gauge: z2.string(),
2042
- rewardToken: z2.string(),
2043
- staked: z2.string(),
2044
- earned: z2.string()
2318
+ output: z3.object({
2319
+ address: z3.string(),
2320
+ positions: z3.array(
2321
+ z3.object({
2322
+ pool: z3.string(),
2323
+ gauge: z3.string(),
2324
+ rewardToken: z3.string(),
2325
+ staked: z3.string(),
2326
+ earned: z3.string()
2045
2327
  })
2046
2328
  ),
2047
- count: z2.number()
2329
+ count: z3.number()
2048
2330
  }),
2049
2331
  examples: [
2050
2332
  {
@@ -2135,11 +2417,11 @@ gauges.command("staked", {
2135
2417
 
2136
2418
  // src/commands/lending.ts
2137
2419
  import { checksumAddress as checksumAddress3, isAddress as isAddress2 } from "@spectratools/cli-shared";
2138
- import { Cli as Cli3, z as z3 } from "incur";
2420
+ import { Cli as Cli3, z as z4 } from "incur";
2139
2421
  import { formatUnits as formatUnits2 } from "viem";
2140
2422
  var MORPHO_DEPLOY_BLOCK = 13947713n;
2141
- var env3 = z3.object({
2142
- ABSTRACT_RPC_URL: z3.string().optional().describe("Abstract RPC URL override")
2423
+ var env3 = z4.object({
2424
+ ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override")
2143
2425
  });
2144
2426
  var morphoAbi = [
2145
2427
  {
@@ -2220,27 +2502,27 @@ var erc20MetadataAbi2 = [
2220
2502
  outputs: [{ type: "uint8" }]
2221
2503
  }
2222
2504
  ];
2223
- var tokenMetaSchema = z3.object({
2224
- address: z3.string(),
2225
- symbol: z3.string(),
2226
- decimals: z3.number()
2505
+ var tokenMetaSchema = z4.object({
2506
+ address: z4.string(),
2507
+ symbol: z4.string(),
2508
+ decimals: z4.number()
2227
2509
  });
2228
- var lendingMarketRowSchema = z3.object({
2229
- marketId: z3.string(),
2510
+ var lendingMarketRowSchema = z4.object({
2511
+ marketId: z4.string(),
2230
2512
  loanToken: tokenMetaSchema,
2231
2513
  collateralToken: tokenMetaSchema,
2232
- oracle: z3.string(),
2233
- irm: z3.string(),
2234
- lltvBps: z3.number(),
2235
- lltvPercent: z3.number(),
2236
- totalSupplyAssets: z3.string(),
2237
- totalBorrowAssets: z3.string(),
2238
- totalSupplyShares: z3.string(),
2239
- totalBorrowShares: z3.string(),
2240
- availableLiquidityAssets: z3.string(),
2241
- utilization: z3.number().nullable(),
2242
- feeWad: z3.string(),
2243
- lastUpdate: z3.number()
2514
+ oracle: z4.string(),
2515
+ irm: z4.string(),
2516
+ lltvBps: z4.number(),
2517
+ lltvPercent: z4.number(),
2518
+ totalSupplyAssets: z4.string(),
2519
+ totalBorrowAssets: z4.string(),
2520
+ totalSupplyShares: z4.string(),
2521
+ totalBorrowShares: z4.string(),
2522
+ availableLiquidityAssets: z4.string(),
2523
+ utilization: z4.number().nullable(),
2524
+ feeWad: z4.string(),
2525
+ lastUpdate: z4.number()
2244
2526
  });
2245
2527
  function isMarketId(value) {
2246
2528
  return /^0x[0-9a-fA-F]{64}$/.test(value);
@@ -2476,21 +2758,21 @@ var lending = Cli3.create("lending", {
2476
2758
  });
2477
2759
  lending.command("markets", {
2478
2760
  description: "List Morpho markets discovered from CreateMarket events.",
2479
- args: z3.object({
2480
- limit: z3.coerce.number().int().positive().max(200).default(25).describe("Max markets to return")
2761
+ args: z4.object({
2762
+ limit: z4.coerce.number().int().positive().max(200).default(25).describe("Max markets to return")
2481
2763
  }),
2482
2764
  env: env3,
2483
- output: z3.object({
2484
- morpho: z3.string(),
2485
- marketCount: z3.number(),
2486
- markets: z3.array(lendingMarketRowSchema),
2487
- totalsByLoanToken: z3.array(
2488
- z3.object({
2489
- token: z3.string(),
2490
- symbol: z3.string(),
2491
- decimals: z3.number(),
2492
- totalSupplyAssets: z3.string(),
2493
- totalBorrowAssets: z3.string()
2765
+ output: z4.object({
2766
+ morpho: z4.string(),
2767
+ marketCount: z4.number(),
2768
+ markets: z4.array(lendingMarketRowSchema),
2769
+ totalsByLoanToken: z4.array(
2770
+ z4.object({
2771
+ token: z4.string(),
2772
+ symbol: z4.string(),
2773
+ decimals: z4.number(),
2774
+ totalSupplyAssets: z4.string(),
2775
+ totalBorrowAssets: z4.string()
2494
2776
  })
2495
2777
  )
2496
2778
  }),
@@ -2537,8 +2819,8 @@ lending.command("markets", {
2537
2819
  });
2538
2820
  lending.command("market", {
2539
2821
  description: "Get details for one Morpho market id (bytes32).",
2540
- args: z3.object({
2541
- marketId: z3.string().describe("Morpho market id (bytes32 hex)")
2822
+ args: z4.object({
2823
+ marketId: z4.string().describe("Morpho market id (bytes32 hex)")
2542
2824
  }),
2543
2825
  env: env3,
2544
2826
  output: lendingMarketRowSchema,
@@ -2598,29 +2880,29 @@ lending.command("market", {
2598
2880
  });
2599
2881
  lending.command("position", {
2600
2882
  description: "Inspect one user position in a Morpho market.",
2601
- args: z3.object({
2602
- marketId: z3.string().describe("Morpho market id (bytes32 hex)"),
2603
- user: z3.string().describe("Position owner address")
2883
+ args: z4.object({
2884
+ marketId: z4.string().describe("Morpho market id (bytes32 hex)"),
2885
+ user: z4.string().describe("Position owner address")
2604
2886
  }),
2605
2887
  env: env3,
2606
- output: z3.object({
2607
- marketId: z3.string(),
2608
- user: z3.string(),
2888
+ output: z4.object({
2889
+ marketId: z4.string(),
2890
+ user: z4.string(),
2609
2891
  loanToken: tokenMetaSchema,
2610
2892
  collateralToken: tokenMetaSchema,
2611
- supplyShares: z3.string(),
2612
- supplyAssetsEstimate: z3.object({
2613
- raw: z3.string(),
2614
- decimal: z3.string()
2893
+ supplyShares: z4.string(),
2894
+ supplyAssetsEstimate: z4.object({
2895
+ raw: z4.string(),
2896
+ decimal: z4.string()
2615
2897
  }),
2616
- borrowShares: z3.string(),
2617
- borrowAssetsEstimate: z3.object({
2618
- raw: z3.string(),
2619
- decimal: z3.string()
2898
+ borrowShares: z4.string(),
2899
+ borrowAssetsEstimate: z4.object({
2900
+ raw: z4.string(),
2901
+ decimal: z4.string()
2620
2902
  }),
2621
- collateralAssets: z3.object({
2622
- raw: z3.string(),
2623
- decimal: z3.string()
2903
+ collateralAssets: z4.object({
2904
+ raw: z4.string(),
2905
+ decimal: z4.string()
2624
2906
  })
2625
2907
  }),
2626
2908
  examples: [
@@ -2751,38 +3033,86 @@ lending.command("position", {
2751
3033
 
2752
3034
  // src/commands/pools.ts
2753
3035
  import { checksumAddress as checksumAddress4, isAddress as isAddress3 } from "@spectratools/cli-shared";
2754
- import { Cli as Cli4, z as z4 } from "incur";
3036
+ import { Cli as Cli4, z as z5 } from "incur";
2755
3037
  import { formatUnits as formatUnits3, parseUnits as parseUnits2 } from "viem";
2756
3038
  var MULTICALL_BATCH_SIZE2 = 100;
2757
- var env4 = z4.object({
2758
- ABSTRACT_RPC_URL: z4.string().optional().describe("Abstract RPC URL override")
3039
+ var DEFAULT_SLIPPAGE_PERCENT2 = 0.5;
3040
+ var DEFAULT_DEADLINE_SECONDS2 = 300;
3041
+ var erc20ApproveAbi = [
3042
+ {
3043
+ type: "function",
3044
+ name: "approve",
3045
+ stateMutability: "nonpayable",
3046
+ inputs: [
3047
+ { name: "spender", type: "address" },
3048
+ { name: "amount", type: "uint256" }
3049
+ ],
3050
+ outputs: [{ name: "", type: "bool" }]
3051
+ },
3052
+ {
3053
+ type: "function",
3054
+ name: "allowance",
3055
+ stateMutability: "view",
3056
+ inputs: [
3057
+ { name: "owner", type: "address" },
3058
+ { name: "account", type: "address" }
3059
+ ],
3060
+ outputs: [{ name: "", type: "uint256" }]
3061
+ }
3062
+ ];
3063
+ var v2RouterSwapAbi = [
3064
+ {
3065
+ type: "function",
3066
+ name: "swapExactTokensForTokens",
3067
+ stateMutability: "nonpayable",
3068
+ inputs: [
3069
+ { name: "amountIn", type: "uint256" },
3070
+ { name: "amountOutMin", type: "uint256" },
3071
+ {
3072
+ name: "routes",
3073
+ type: "tuple[]",
3074
+ components: [
3075
+ { name: "from", type: "address" },
3076
+ { name: "to", type: "address" },
3077
+ { name: "stable", type: "bool" },
3078
+ { name: "factory", type: "address" }
3079
+ ]
3080
+ },
3081
+ { name: "to", type: "address" },
3082
+ { name: "deadline", type: "uint256" }
3083
+ ],
3084
+ outputs: [{ name: "amounts", type: "uint256[]" }]
3085
+ }
3086
+ ];
3087
+ var env4 = z5.object({
3088
+ ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override")
2759
3089
  });
2760
- var tokenSchema2 = z4.object({
2761
- address: z4.string(),
2762
- symbol: z4.string(),
2763
- decimals: z4.number()
3090
+ var tokenSchema2 = z5.object({
3091
+ address: z5.string(),
3092
+ symbol: z5.string(),
3093
+ decimals: z5.number()
2764
3094
  });
2765
- var amountSchema = z4.object({
2766
- raw: z4.string(),
2767
- decimal: z4.string()
3095
+ var amountSchema = z5.object({
3096
+ raw: z5.string(),
3097
+ decimal: z5.string()
2768
3098
  });
2769
- var feeSchema = z4.object({
2770
- feeBps: z4.number(),
2771
- feePercent: z4.number()
3099
+ var feeSchema = z5.object({
3100
+ feeBps: z5.number(),
3101
+ feePercent: z5.number()
2772
3102
  }).nullable();
2773
- var poolSummarySchema = z4.object({
2774
- pool: z4.string(),
2775
- pair: z4.string(),
2776
- stable: z4.boolean(),
2777
- poolType: z4.enum(["stable", "volatile"]),
3103
+ var poolSummarySchema = z5.object({
3104
+ pool: z5.string(),
3105
+ pair: z5.string(),
3106
+ stable: z5.boolean(),
3107
+ poolType: z5.enum(["stable", "volatile"]),
2778
3108
  token0: tokenSchema2,
2779
3109
  token1: tokenSchema2,
2780
- reserves: z4.object({
3110
+ reserves: z5.object({
2781
3111
  token0: amountSchema,
2782
3112
  token1: amountSchema,
2783
- blockTimestampLast: z4.number()
3113
+ blockTimestampLast: z5.number()
2784
3114
  }),
2785
- totalSupply: z4.string(),
3115
+ totalSupply: z5.string(),
2786
3116
  fee: feeSchema
2787
3117
  });
2788
3118
  var erc20MetadataAbi3 = [
@@ -2987,17 +3317,17 @@ var pools = Cli4.create("pools", {
2987
3317
  });
2988
3318
  pools.command("list", {
2989
3319
  description: "List V2 pools with token pairs, reserves, and stable/volatile type.",
2990
- options: z4.object({
2991
- offset: z4.coerce.number().int().nonnegative().default(0).describe("Pool index offset"),
2992
- limit: z4.coerce.number().int().positive().max(500).default(50).describe("Maximum pools to return (max 500)")
3320
+ options: z5.object({
3321
+ offset: z5.coerce.number().int().nonnegative().default(0).describe("Pool index offset"),
3322
+ limit: z5.coerce.number().int().positive().max(500).default(50).describe("Maximum pools to return (max 500)")
2993
3323
  }),
2994
3324
  env: env4,
2995
- output: z4.object({
2996
- total: z4.number(),
2997
- offset: z4.number(),
2998
- limit: z4.number(),
2999
- count: z4.number(),
3000
- pools: z4.array(poolSummarySchema)
3325
+ output: z5.object({
3326
+ total: z5.number(),
3327
+ offset: z5.number(),
3328
+ limit: z5.number(),
3329
+ count: z5.number(),
3330
+ pools: z5.array(poolSummarySchema)
3001
3331
  }),
3002
3332
  async run(c) {
3003
3333
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
@@ -3075,14 +3405,14 @@ pools.command("list", {
3075
3405
  });
3076
3406
  pools.command("pool", {
3077
3407
  description: "Get detailed state for one V2 pool.",
3078
- args: z4.object({
3079
- address: z4.string().describe("Pool address")
3408
+ args: z5.object({
3409
+ address: z5.string().describe("Pool address")
3080
3410
  }),
3081
3411
  env: env4,
3082
- output: z4.object({
3412
+ output: z5.object({
3083
3413
  pool: poolSummarySchema.extend({
3084
- poolFees: z4.string(),
3085
- factory: z4.string()
3414
+ poolFees: z5.string(),
3415
+ factory: z5.string()
3086
3416
  })
3087
3417
  }),
3088
3418
  async run(c) {
@@ -3181,23 +3511,23 @@ pools.command("pool", {
3181
3511
  });
3182
3512
  pools.command("quote", {
3183
3513
  description: "Quote a single-hop V2 swap between tokenIn and tokenOut.",
3184
- args: z4.object({
3185
- tokenIn: z4.string().describe("Input token address"),
3186
- tokenOut: z4.string().describe("Output token address"),
3187
- amountIn: z4.string().describe("Input amount in human-readable decimal units")
3514
+ args: z5.object({
3515
+ tokenIn: z5.string().describe("Input token address"),
3516
+ tokenOut: z5.string().describe("Output token address"),
3517
+ amountIn: z5.string().describe("Input amount in human-readable decimal units")
3188
3518
  }),
3189
- options: z4.object({
3190
- stable: z4.boolean().default(false).describe("Use stable pool route (default: volatile)")
3519
+ options: z5.object({
3520
+ stable: z5.boolean().default(false).describe("Use stable pool route (default: volatile)")
3191
3521
  }),
3192
3522
  env: env4,
3193
- output: z4.object({
3194
- pool: z4.string(),
3195
- stable: z4.boolean(),
3523
+ output: z5.object({
3524
+ pool: z5.string(),
3525
+ stable: z5.boolean(),
3196
3526
  tokenIn: tokenSchema2,
3197
3527
  tokenOut: tokenSchema2,
3198
3528
  amountIn: amountSchema,
3199
3529
  amountOut: amountSchema,
3200
- priceOutPerIn: z4.number().nullable()
3530
+ priceOutPerIn: z5.number().nullable()
3201
3531
  }),
3202
3532
  async run(c) {
3203
3533
  if (!isAddress3(c.args.tokenIn) || !isAddress3(c.args.tokenOut)) {
@@ -3297,14 +3627,14 @@ pools.command("quote", {
3297
3627
  });
3298
3628
  pools.command("fees", {
3299
3629
  description: "Read V2 fee configuration for a pool address.",
3300
- args: z4.object({
3301
- pool: z4.string().describe("Pool address")
3630
+ args: z5.object({
3631
+ pool: z5.string().describe("Pool address")
3302
3632
  }),
3303
3633
  env: env4,
3304
- output: z4.object({
3305
- pool: z4.string(),
3306
- pair: z4.string(),
3307
- stable: z4.boolean(),
3634
+ output: z5.object({
3635
+ pool: z5.string(),
3636
+ pair: z5.string(),
3637
+ stable: z5.boolean(),
3308
3638
  activeFee: feeSchema,
3309
3639
  stableFee: feeSchema,
3310
3640
  volatileFee: feeSchema
@@ -3377,12 +3707,173 @@ pools.command("fees", {
3377
3707
  );
3378
3708
  }
3379
3709
  });
3710
+ pools.command("swap", {
3711
+ description: "Execute a single-hop V2 AMM swap. Quotes the expected output, applies slippage tolerance, approves the router if needed, and broadcasts the swap transaction.",
3712
+ options: z5.object({
3713
+ "token-in": z5.string().describe("Input token address"),
3714
+ "token-out": z5.string().describe("Output token address"),
3715
+ "amount-in": z5.string().describe("Input amount in wei"),
3716
+ slippage: z5.coerce.number().min(0).max(100).default(DEFAULT_SLIPPAGE_PERCENT2).describe("Slippage tolerance in percent (default: 0.5)"),
3717
+ deadline: z5.coerce.number().int().positive().default(DEFAULT_DEADLINE_SECONDS2).describe("Transaction deadline in seconds from now (default: 300)"),
3718
+ stable: z5.boolean().default(false).describe("Use stable pool route (default: volatile)")
3719
+ }).merge(writeOptions),
3720
+ env: writeEnv,
3721
+ output: z5.object({
3722
+ pool: z5.string(),
3723
+ stable: z5.boolean(),
3724
+ tokenIn: tokenSchema2,
3725
+ tokenOut: tokenSchema2,
3726
+ amountIn: amountSchema,
3727
+ expectedAmountOut: amountSchema,
3728
+ minAmountOut: amountSchema,
3729
+ slippagePercent: z5.number(),
3730
+ effectivePrice: z5.number().nullable(),
3731
+ tx: z5.union([
3732
+ z5.object({
3733
+ txHash: z5.string(),
3734
+ blockNumber: z5.number(),
3735
+ gasUsed: z5.string()
3736
+ }),
3737
+ z5.object({
3738
+ dryRun: z5.literal(true),
3739
+ estimatedGas: z5.string(),
3740
+ simulationResult: z5.unknown()
3741
+ })
3742
+ ])
3743
+ }),
3744
+ async run(c) {
3745
+ const tokenInRaw = c.options["token-in"];
3746
+ const tokenOutRaw = c.options["token-out"];
3747
+ if (!isAddress3(tokenInRaw) || !isAddress3(tokenOutRaw)) {
3748
+ return c.error({
3749
+ code: "INVALID_ADDRESS",
3750
+ message: "token-in and token-out must both be valid 0x-prefixed 20-byte addresses."
3751
+ });
3752
+ }
3753
+ const tokenIn = toAddress(tokenInRaw);
3754
+ const tokenOut = toAddress(tokenOutRaw);
3755
+ const amountInRaw = BigInt(c.options["amount-in"]);
3756
+ if (amountInRaw <= 0n) {
3757
+ return c.error({
3758
+ code: "INVALID_AMOUNT",
3759
+ message: "amount-in must be a positive integer in wei."
3760
+ });
3761
+ }
3762
+ const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
3763
+ const tokenMeta = await readTokenMetadata3(client, [tokenIn, tokenOut]);
3764
+ const inMeta = tokenMeta.get(tokenIn.toLowerCase()) ?? fallbackTokenMeta(tokenIn);
3765
+ const outMeta = tokenMeta.get(tokenOut.toLowerCase()) ?? fallbackTokenMeta(tokenOut);
3766
+ const poolAddress = await client.readContract({
3767
+ abi: poolFactoryAbi,
3768
+ address: ABOREAN_V2_ADDRESSES.poolFactory,
3769
+ functionName: "getPool",
3770
+ args: [tokenIn, tokenOut, c.options.stable]
3771
+ });
3772
+ if (poolAddress.toLowerCase() === ZERO_ADDRESS.toLowerCase()) {
3773
+ return c.error({
3774
+ code: "POOL_NOT_FOUND",
3775
+ message: `No ${c.options.stable ? "stable" : "volatile"} V2 pool found for pair ${checksumAddress4(tokenIn)}/${checksumAddress4(tokenOut)}.`
3776
+ });
3777
+ }
3778
+ const amounts = await client.readContract({
3779
+ abi: v2RouterAbi,
3780
+ address: ABOREAN_V2_ADDRESSES.router,
3781
+ functionName: "getAmountsOut",
3782
+ args: [
3783
+ amountInRaw,
3784
+ [
3785
+ {
3786
+ from: tokenIn,
3787
+ to: tokenOut,
3788
+ stable: c.options.stable,
3789
+ factory: ABOREAN_V2_ADDRESSES.poolFactory
3790
+ }
3791
+ ]
3792
+ ]
3793
+ });
3794
+ const expectedAmountOut = amounts[amounts.length - 1] ?? 0n;
3795
+ if (expectedAmountOut === 0n) {
3796
+ return c.error({
3797
+ code: "ZERO_QUOTE",
3798
+ message: "Router returned zero output amount. The pool may have insufficient liquidity."
3799
+ });
3800
+ }
3801
+ const slippageBps = Math.round(c.options.slippage * 100);
3802
+ const minAmountOut = expectedAmountOut * BigInt(1e4 - slippageBps) / 10000n;
3803
+ const deadlineTimestamp = BigInt(Math.floor(Date.now() / 1e3) + c.options.deadline);
3804
+ const account = resolveAccount(c.env);
3805
+ if (!c.options["dry-run"]) {
3806
+ const currentAllowance = await client.readContract({
3807
+ abi: erc20ApproveAbi,
3808
+ address: tokenIn,
3809
+ functionName: "allowance",
3810
+ args: [account.address, ABOREAN_V2_ADDRESSES.router]
3811
+ });
3812
+ if (currentAllowance < amountInRaw) {
3813
+ await aboreanWriteTx({
3814
+ env: c.env,
3815
+ options: { ...c.options, "dry-run": false },
3816
+ address: tokenIn,
3817
+ abi: erc20ApproveAbi,
3818
+ functionName: "approve",
3819
+ args: [ABOREAN_V2_ADDRESSES.router, amountInRaw]
3820
+ });
3821
+ }
3822
+ }
3823
+ const tx = await aboreanWriteTx({
3824
+ env: c.env,
3825
+ options: c.options,
3826
+ address: ABOREAN_V2_ADDRESSES.router,
3827
+ abi: v2RouterSwapAbi,
3828
+ functionName: "swapExactTokensForTokens",
3829
+ args: [
3830
+ amountInRaw,
3831
+ minAmountOut,
3832
+ [
3833
+ {
3834
+ from: tokenIn,
3835
+ to: tokenOut,
3836
+ stable: c.options.stable,
3837
+ factory: ABOREAN_V2_ADDRESSES.poolFactory
3838
+ }
3839
+ ],
3840
+ account.address,
3841
+ deadlineTimestamp
3842
+ ]
3843
+ });
3844
+ const amountInDecimal = formatUnits3(amountInRaw, inMeta.decimals);
3845
+ const expectedOutDecimal = formatUnits3(expectedAmountOut, outMeta.decimals);
3846
+ const minOutDecimal = formatUnits3(minAmountOut, outMeta.decimals);
3847
+ const ratio = Number(expectedOutDecimal) / Number(amountInDecimal);
3848
+ return c.ok({
3849
+ pool: checksumAddress4(poolAddress),
3850
+ stable: c.options.stable,
3851
+ tokenIn: inMeta,
3852
+ tokenOut: outMeta,
3853
+ amountIn: {
3854
+ raw: amountInRaw.toString(),
3855
+ decimal: amountInDecimal
3856
+ },
3857
+ expectedAmountOut: {
3858
+ raw: expectedAmountOut.toString(),
3859
+ decimal: expectedOutDecimal
3860
+ },
3861
+ minAmountOut: {
3862
+ raw: minAmountOut.toString(),
3863
+ decimal: minOutDecimal
3864
+ },
3865
+ slippagePercent: c.options.slippage,
3866
+ effectivePrice: Number(amountInDecimal) === 0 ? null : finiteOrNull3(ratio),
3867
+ tx
3868
+ });
3869
+ }
3870
+ });
3380
3871
 
3381
3872
  // src/commands/vaults.ts
3382
3873
  import { checksumAddress as checksumAddress5, isAddress as isAddress4 } from "@spectratools/cli-shared";
3383
- import { Cli as Cli5, z as z5 } from "incur";
3384
- var env5 = z5.object({
3385
- ABSTRACT_RPC_URL: z5.string().optional().describe("Abstract RPC URL override")
3874
+ import { Cli as Cli5, z as z6 } from "incur";
3875
+ var env5 = z6.object({
3876
+ ABSTRACT_RPC_URL: z6.string().optional().describe("Abstract RPC URL override")
3386
3877
  });
3387
3878
  var relayAbi = [
3388
3879
  {
@@ -3446,22 +3937,22 @@ var votingEscrowLiteAbi = [
3446
3937
  outputs: [{ type: "uint256" }]
3447
3938
  }
3448
3939
  ];
3449
- var relayRowSchema = z5.object({
3450
- label: z5.string(),
3451
- relay: z5.string(),
3452
- name: z5.string(),
3453
- factoryType: z5.enum(["autoCompounder", "autoConverter"]),
3454
- managedTokenId: z5.string(),
3455
- managedVotingPower: z5.string(),
3456
- relayToken: z5.object({
3457
- address: z5.string(),
3458
- symbol: z5.string(),
3459
- decimals: z5.number()
3940
+ var relayRowSchema = z6.object({
3941
+ label: z6.string(),
3942
+ relay: z6.string(),
3943
+ name: z6.string(),
3944
+ factoryType: z6.enum(["autoCompounder", "autoConverter"]),
3945
+ managedTokenId: z6.string(),
3946
+ managedVotingPower: z6.string(),
3947
+ relayToken: z6.object({
3948
+ address: z6.string(),
3949
+ symbol: z6.string(),
3950
+ decimals: z6.number()
3460
3951
  }),
3461
- relayTokenBalance: z5.string(),
3462
- keeperLastRun: z5.number(),
3463
- keeperLastRunRelative: z5.string(),
3464
- secondsSinceKeeperRun: z5.number()
3952
+ relayTokenBalance: z6.string(),
3953
+ keeperLastRun: z6.number(),
3954
+ keeperLastRunRelative: z6.string(),
3955
+ secondsSinceKeeperRun: z6.number()
3465
3956
  });
3466
3957
  var KNOWN_RELAYS = [
3467
3958
  {
@@ -3587,17 +4078,17 @@ var vaults = Cli5.create("vaults", {
3587
4078
  vaults.command("list", {
3588
4079
  description: "List known Aborean relay vaults with keeper and veNFT state.",
3589
4080
  env: env5,
3590
- output: z5.object({
3591
- relayCount: z5.number(),
3592
- relays: z5.array(relayRowSchema),
3593
- totals: z5.object({
3594
- managedVotingPower: z5.string(),
3595
- relayTokenBalances: z5.array(
3596
- z5.object({
3597
- token: z5.string(),
3598
- symbol: z5.string(),
3599
- decimals: z5.number(),
3600
- balance: z5.string()
4081
+ output: z6.object({
4082
+ relayCount: z6.number(),
4083
+ relays: z6.array(relayRowSchema),
4084
+ totals: z6.object({
4085
+ managedVotingPower: z6.string(),
4086
+ relayTokenBalances: z6.array(
4087
+ z6.object({
4088
+ token: z6.string(),
4089
+ symbol: z6.string(),
4090
+ decimals: z6.number(),
4091
+ balance: z6.string()
3601
4092
  })
3602
4093
  )
3603
4094
  })
@@ -3636,8 +4127,8 @@ vaults.command("list", {
3636
4127
  });
3637
4128
  vaults.command("relay", {
3638
4129
  description: "Inspect one relay vault by address.",
3639
- args: z5.object({
3640
- relay: z5.string().describe("Relay vault contract address")
4130
+ args: z6.object({
4131
+ relay: z6.string().describe("Relay vault contract address")
3641
4132
  }),
3642
4133
  env: env5,
3643
4134
  output: relayRowSchema,
@@ -3689,9 +4180,9 @@ vaults.command("relay", {
3689
4180
  });
3690
4181
 
3691
4182
  // src/commands/ve.ts
3692
- import { Cli as Cli6, z as z6 } from "incur";
3693
- var env6 = z6.object({
3694
- ABSTRACT_RPC_URL: z6.string().optional().describe("Abstract RPC URL override")
4183
+ import { Cli as Cli6, z as z7 } from "incur";
4184
+ var env6 = z7.object({
4185
+ ABSTRACT_RPC_URL: z7.string().optional().describe("Abstract RPC URL override")
3695
4186
  });
3696
4187
  var ve = Cli6.create("ve", {
3697
4188
  description: "Inspect Aborean VotingEscrow (veABX) global and per-NFT lock state."
@@ -3699,16 +4190,16 @@ var ve = Cli6.create("ve", {
3699
4190
  ve.command("stats", {
3700
4191
  description: "Get global VotingEscrow supply, locks, and decay checkpoint data.",
3701
4192
  env: env6,
3702
- output: z6.object({
3703
- token: z6.string(),
3704
- totalVotingPower: z6.string(),
3705
- totalLocked: z6.string(),
3706
- permanentLocked: z6.string(),
3707
- epoch: z6.number(),
3708
- decayBias: z6.string(),
3709
- decaySlope: z6.string(),
3710
- lastCheckpointTimestamp: z6.number(),
3711
- lastCheckpointBlock: z6.number()
4193
+ output: z7.object({
4194
+ token: z7.string(),
4195
+ totalVotingPower: z7.string(),
4196
+ totalLocked: z7.string(),
4197
+ permanentLocked: z7.string(),
4198
+ epoch: z7.number(),
4199
+ decayBias: z7.string(),
4200
+ decaySlope: z7.string(),
4201
+ lastCheckpointTimestamp: z7.number(),
4202
+ lastCheckpointBlock: z7.number()
3712
4203
  }),
3713
4204
  examples: [{ description: "Show global veABX state and decay metrics" }],
3714
4205
  async run(c) {
@@ -3779,17 +4270,17 @@ ve.command("stats", {
3779
4270
  });
3780
4271
  ve.command("lock", {
3781
4272
  description: "Get lock details and voting power for one veNFT token id.",
3782
- args: z6.object({
3783
- tokenId: z6.coerce.number().int().nonnegative().describe("veNFT token id")
4273
+ args: z7.object({
4274
+ tokenId: z7.coerce.number().int().nonnegative().describe("veNFT token id")
3784
4275
  }),
3785
4276
  env: env6,
3786
- output: z6.object({
3787
- tokenId: z6.number(),
3788
- owner: z6.string(),
3789
- amount: z6.string(),
3790
- unlockTime: z6.number(),
3791
- isPermanent: z6.boolean(),
3792
- votingPower: z6.string()
4277
+ output: z7.object({
4278
+ tokenId: z7.number(),
4279
+ owner: z7.string(),
4280
+ amount: z7.string(),
4281
+ unlockTime: z7.number(),
4282
+ isPermanent: z7.boolean(),
4283
+ votingPower: z7.string()
3793
4284
  }),
3794
4285
  examples: [{ args: { tokenId: 1 }, description: "Inspect lock details for veNFT #1" }],
3795
4286
  async run(c) {
@@ -3846,22 +4337,22 @@ ve.command("lock", {
3846
4337
  });
3847
4338
  ve.command("locks", {
3848
4339
  description: "List all veNFT locks owned by an address.",
3849
- args: z6.object({
3850
- address: z6.string().describe("Owner address")
4340
+ args: z7.object({
4341
+ address: z7.string().describe("Owner address")
3851
4342
  }),
3852
4343
  env: env6,
3853
- output: z6.object({
3854
- address: z6.string(),
3855
- locks: z6.array(
3856
- z6.object({
3857
- tokenId: z6.string(),
3858
- amount: z6.string(),
3859
- unlockTime: z6.number(),
3860
- isPermanent: z6.boolean(),
3861
- votingPower: z6.string()
4344
+ output: z7.object({
4345
+ address: z7.string(),
4346
+ locks: z7.array(
4347
+ z7.object({
4348
+ tokenId: z7.string(),
4349
+ amount: z7.string(),
4350
+ unlockTime: z7.number(),
4351
+ isPermanent: z7.boolean(),
4352
+ votingPower: z7.string()
3862
4353
  })
3863
4354
  ),
3864
- count: z6.number()
4355
+ count: z7.number()
3865
4356
  }),
3866
4357
  examples: [
3867
4358
  {
@@ -3953,13 +4444,13 @@ ve.command("locks", {
3953
4444
  });
3954
4445
  ve.command("voting-power", {
3955
4446
  description: "Get current voting power for one veNFT token id.",
3956
- args: z6.object({
3957
- tokenId: z6.coerce.number().int().nonnegative().describe("veNFT token id")
4447
+ args: z7.object({
4448
+ tokenId: z7.coerce.number().int().nonnegative().describe("veNFT token id")
3958
4449
  }),
3959
4450
  env: env6,
3960
- output: z6.object({
3961
- tokenId: z6.number(),
3962
- votingPower: z6.string()
4451
+ output: z7.object({
4452
+ tokenId: z7.number(),
4453
+ votingPower: z7.string()
3963
4454
  }),
3964
4455
  examples: [{ args: { tokenId: 1 }, description: "Get current voting power for veNFT #1" }],
3965
4456
  async run(c) {
@@ -3997,9 +4488,9 @@ ve.command("voting-power", {
3997
4488
  });
3998
4489
 
3999
4490
  // src/commands/voter.ts
4000
- import { Cli as Cli7, z as z7 } from "incur";
4001
- var env7 = z7.object({
4002
- ABSTRACT_RPC_URL: z7.string().optional().describe("Abstract RPC URL override")
4491
+ import { Cli as Cli7, z as z8 } from "incur";
4492
+ var env7 = z8.object({
4493
+ ABSTRACT_RPC_URL: z8.string().optional().describe("Abstract RPC URL override")
4003
4494
  });
4004
4495
  async function discoverPools(client) {
4005
4496
  const [v2PoolCount, clPoolCount] = await Promise.all([
@@ -4044,14 +4535,14 @@ var voter = Cli7.create("voter", {
4044
4535
  voter.command("epoch", {
4045
4536
  description: "Show current emissions epoch timing from Minter.",
4046
4537
  env: env7,
4047
- output: z7.object({
4048
- activePeriod: z7.number(),
4049
- epochEnd: z7.number(),
4050
- secondsRemaining: z7.number(),
4051
- timeRemaining: z7.string(),
4052
- weekSeconds: z7.number(),
4053
- epochCount: z7.number(),
4054
- weeklyEmission: z7.string()
4538
+ output: z8.object({
4539
+ activePeriod: z8.number(),
4540
+ epochEnd: z8.number(),
4541
+ secondsRemaining: z8.number(),
4542
+ timeRemaining: z8.string(),
4543
+ weekSeconds: z8.number(),
4544
+ epochCount: z8.number(),
4545
+ weeklyEmission: z8.string()
4055
4546
  }),
4056
4547
  examples: [{ description: "Inspect current voter epoch boundaries" }],
4057
4548
  async run(c) {
@@ -4111,16 +4602,16 @@ voter.command("epoch", {
4111
4602
  voter.command("weights", {
4112
4603
  description: "Show current pool voting weight distribution.",
4113
4604
  env: env7,
4114
- output: z7.object({
4115
- totalWeight: z7.string(),
4116
- pools: z7.array(
4117
- z7.object({
4118
- pool: z7.string(),
4119
- gauge: z7.string(),
4120
- weight: z7.string()
4605
+ output: z8.object({
4606
+ totalWeight: z8.string(),
4607
+ pools: z8.array(
4608
+ z8.object({
4609
+ pool: z8.string(),
4610
+ gauge: z8.string(),
4611
+ weight: z8.string()
4121
4612
  })
4122
4613
  ),
4123
- count: z7.number()
4614
+ count: z8.number()
4124
4615
  }),
4125
4616
  examples: [{ description: "List all pools with non-zero voting weight" }],
4126
4617
  async run(c) {
@@ -4199,19 +4690,19 @@ voter.command("weights", {
4199
4690
  });
4200
4691
  voter.command("rewards", {
4201
4692
  description: "Show claimable rebase rewards and voting context for a veNFT.",
4202
- args: z7.object({
4203
- tokenId: z7.coerce.number().int().nonnegative().describe("veNFT token id")
4693
+ args: z8.object({
4694
+ tokenId: z8.coerce.number().int().nonnegative().describe("veNFT token id")
4204
4695
  }),
4205
4696
  env: env7,
4206
- output: z7.object({
4207
- tokenId: z7.number(),
4208
- rewardToken: z7.string(),
4209
- claimableRebase: z7.string(),
4210
- timeCursor: z7.number(),
4211
- lastTokenTime: z7.number(),
4212
- distributorStartTime: z7.number(),
4213
- usedWeight: z7.string(),
4214
- lastVoted: z7.number()
4697
+ output: z8.object({
4698
+ tokenId: z8.number(),
4699
+ rewardToken: z8.string(),
4700
+ claimableRebase: z8.string(),
4701
+ timeCursor: z8.number(),
4702
+ lastTokenTime: z8.number(),
4703
+ distributorStartTime: z8.number(),
4704
+ usedWeight: z8.string(),
4705
+ lastVoted: z8.number()
4215
4706
  }),
4216
4707
  examples: [{ args: { tokenId: 1 }, description: "Check claimable voter/distributor rewards" }],
4217
4708
  async run(c) {
@@ -4298,22 +4789,22 @@ voter.command("rewards", {
4298
4789
  });
4299
4790
  voter.command("bribes", {
4300
4791
  description: "Show active bribe reward tokens and current-epoch amounts for a pool.",
4301
- args: z7.object({
4302
- pool: z7.string().describe("Pool address")
4792
+ args: z8.object({
4793
+ pool: z8.string().describe("Pool address")
4303
4794
  }),
4304
4795
  env: env7,
4305
- output: z7.object({
4306
- pool: z7.string(),
4307
- gauge: z7.string(),
4308
- bribeContract: z7.string(),
4309
- epochStart: z7.number(),
4310
- rewardTokens: z7.array(
4311
- z7.object({
4312
- token: z7.string(),
4313
- epochAmount: z7.string()
4796
+ output: z8.object({
4797
+ pool: z8.string(),
4798
+ gauge: z8.string(),
4799
+ bribeContract: z8.string(),
4800
+ epochStart: z8.number(),
4801
+ rewardTokens: z8.array(
4802
+ z8.object({
4803
+ token: z8.string(),
4804
+ epochAmount: z8.string()
4314
4805
  })
4315
4806
  ),
4316
- count: z7.number()
4807
+ count: z8.number()
4317
4808
  }),
4318
4809
  examples: [
4319
4810
  {
@@ -4568,8 +5059,8 @@ cli.command(voter);
4568
5059
  cli.command(cl);
4569
5060
  cli.command(vaults);
4570
5061
  cli.command(lending);
4571
- var rootEnv = z8.object({
4572
- ABSTRACT_RPC_URL: z8.string().optional().describe("Abstract RPC URL override")
5062
+ var rootEnv = z9.object({
5063
+ ABSTRACT_RPC_URL: z9.string().optional().describe("Abstract RPC URL override")
4573
5064
  });
4574
5065
  var erc20MetadataAbi4 = [
4575
5066
  {
@@ -4774,65 +5265,65 @@ async function readTopV2PoolsSnapshot(client, limit) {
4774
5265
  cli.command("status", {
4775
5266
  description: "Cross-protocol Aborean snapshot (TVL estimates, epoch, top pools, ve lock, vaults, Morpho lending).",
4776
5267
  env: rootEnv,
4777
- output: z8.object({
4778
- v2PoolCount: z8.number().describe("Number of V2 AMM pools"),
4779
- clPoolCount: z8.number().describe("Number of Slipstream (CL) pools"),
4780
- gaugeCount: z8.number().describe("Number of pools with gauges"),
4781
- totalVotingWeight: z8.string().describe("Total voting weight (wei)"),
4782
- veABXTotalSupply: z8.string().describe("Total veABX supply (wei)"),
4783
- veABXLockedSupply: z8.string().describe("Total ABX locked in VotingEscrow (wei)"),
4784
- epoch: z8.object({
4785
- activePeriod: z8.number(),
4786
- epochEnd: z8.number(),
4787
- secondsRemaining: z8.number(),
4788
- epochCount: z8.number(),
4789
- weeklyEmission: z8.string()
5268
+ output: z9.object({
5269
+ v2PoolCount: z9.number().describe("Number of V2 AMM pools"),
5270
+ clPoolCount: z9.number().describe("Number of Slipstream (CL) pools"),
5271
+ gaugeCount: z9.number().describe("Number of pools with gauges"),
5272
+ totalVotingWeight: z9.string().describe("Total voting weight (wei)"),
5273
+ veABXTotalSupply: z9.string().describe("Total veABX supply (wei)"),
5274
+ veABXLockedSupply: z9.string().describe("Total ABX locked in VotingEscrow (wei)"),
5275
+ epoch: z9.object({
5276
+ activePeriod: z9.number(),
5277
+ epochEnd: z9.number(),
5278
+ secondsRemaining: z9.number(),
5279
+ epochCount: z9.number(),
5280
+ weeklyEmission: z9.string()
4790
5281
  }),
4791
- topPools: z8.array(
4792
- z8.object({
4793
- pool: z8.string(),
4794
- pair: z8.string(),
4795
- poolType: z8.enum(["stable", "volatile"]),
4796
- token0: z8.object({
4797
- address: z8.string(),
4798
- symbol: z8.string(),
4799
- decimals: z8.number()
5282
+ topPools: z9.array(
5283
+ z9.object({
5284
+ pool: z9.string(),
5285
+ pair: z9.string(),
5286
+ poolType: z9.enum(["stable", "volatile"]),
5287
+ token0: z9.object({
5288
+ address: z9.string(),
5289
+ symbol: z9.string(),
5290
+ decimals: z9.number()
4800
5291
  }),
4801
- token1: z8.object({
4802
- address: z8.string(),
4803
- symbol: z8.string(),
4804
- decimals: z8.number()
5292
+ token1: z9.object({
5293
+ address: z9.string(),
5294
+ symbol: z9.string(),
5295
+ decimals: z9.number()
4805
5296
  }),
4806
- reserves: z8.object({
4807
- token0: z8.string(),
4808
- token1: z8.string()
5297
+ reserves: z9.object({
5298
+ token0: z9.string(),
5299
+ token1: z9.string()
4809
5300
  }),
4810
- tvlEstimateUnits: z8.number()
5301
+ tvlEstimateUnits: z9.number()
4811
5302
  })
4812
5303
  ),
4813
- tvl: z8.object({
4814
- v2ReserveUnitEstimate: z8.number(),
4815
- vaultManagedVotingPower: z8.string()
5304
+ tvl: z9.object({
5305
+ v2ReserveUnitEstimate: z9.number(),
5306
+ vaultManagedVotingPower: z9.string()
4816
5307
  }),
4817
- vaults: z8.object({
4818
- relayCount: z8.number(),
4819
- managedVotingPower: z8.string(),
4820
- note: z8.string().nullable()
5308
+ vaults: z9.object({
5309
+ relayCount: z9.number(),
5310
+ managedVotingPower: z9.string(),
5311
+ note: z9.string().nullable()
4821
5312
  }),
4822
- lending: z8.object({
4823
- available: z8.boolean(),
4824
- morpho: z8.string(),
4825
- marketCount: z8.number(),
4826
- supplyByLoanToken: z8.array(
4827
- z8.object({
4828
- token: z8.string(),
4829
- symbol: z8.string(),
4830
- decimals: z8.number(),
4831
- totalSupplyAssets: z8.string(),
4832
- totalBorrowAssets: z8.string()
5313
+ lending: z9.object({
5314
+ available: z9.boolean(),
5315
+ morpho: z9.string(),
5316
+ marketCount: z9.number(),
5317
+ supplyByLoanToken: z9.array(
5318
+ z9.object({
5319
+ token: z9.string(),
5320
+ symbol: z9.string(),
5321
+ decimals: z9.number(),
5322
+ totalSupplyAssets: z9.string(),
5323
+ totalBorrowAssets: z9.string()
4833
5324
  })
4834
5325
  ),
4835
- note: z8.string().nullable()
5326
+ note: z9.string().nullable()
4836
5327
  })
4837
5328
  }),
4838
5329
  examples: [{ description: "Fetch the current Aborean protocol status" }],