@spectratools/aborean-cli 0.6.0 → 0.7.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 +760 -235
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1352,10 +1352,32 @@ cl.command("pools", {
1352
1352
  poolStates.flatMap((pool) => [pool.token0, pool.token1])
1353
1353
  );
1354
1354
  const rows = poolStates.map((pool) => toPoolRow(pool, tokenMeta));
1355
- return c.ok({
1356
- count: rows.length,
1357
- pools: rows
1358
- });
1355
+ const firstPool = rows[0];
1356
+ return c.ok(
1357
+ {
1358
+ count: rows.length,
1359
+ pools: rows
1360
+ },
1361
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
1362
+ cta: {
1363
+ description: "Explore CL pools:",
1364
+ commands: [
1365
+ ...firstPool ? [
1366
+ {
1367
+ command: "cl pool",
1368
+ args: { pool: firstPool.pool },
1369
+ description: `Inspect ${firstPool.pair}`
1370
+ }
1371
+ ] : [],
1372
+ {
1373
+ command: "cl positions",
1374
+ args: { owner: "<address>" },
1375
+ description: "List CL positions for an address"
1376
+ }
1377
+ ]
1378
+ }
1379
+ }
1380
+ );
1359
1381
  }
1360
1382
  });
1361
1383
  cl.command("pool", {
@@ -1378,9 +1400,33 @@ cl.command("pool", {
1378
1400
  const checksummedPool = checksumAddress(c.args.pool);
1379
1401
  const [poolState] = await readPoolStates(client, [checksummedPool]);
1380
1402
  const tokenMeta = await readTokenMetadata(client, [poolState.token0, poolState.token1]);
1381
- return c.ok({
1382
- pool: toPoolRow(poolState, tokenMeta)
1383
- });
1403
+ const row = toPoolRow(poolState, tokenMeta);
1404
+ return c.ok(
1405
+ {
1406
+ pool: row
1407
+ },
1408
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
1409
+ cta: {
1410
+ description: "Next steps:",
1411
+ commands: [
1412
+ {
1413
+ command: "cl quote",
1414
+ args: {
1415
+ tokenIn: row.token0.address,
1416
+ tokenOut: row.token1.address,
1417
+ amountIn: "1"
1418
+ },
1419
+ description: `Quote a ${row.token0.symbol} \u2192 ${row.token1.symbol} swap`
1420
+ },
1421
+ {
1422
+ command: "cl positions",
1423
+ args: { owner: "<address>" },
1424
+ description: "List positions in this pool"
1425
+ }
1426
+ ]
1427
+ }
1428
+ }
1429
+ );
1384
1430
  }
1385
1431
  });
1386
1432
  cl.command("positions", {
@@ -1466,11 +1512,35 @@ cl.command("positions", {
1466
1512
  }
1467
1513
  };
1468
1514
  });
1469
- return c.ok({
1470
- owner,
1471
- count: positions.length,
1472
- positions
1473
- });
1515
+ const firstPosition = positions[0];
1516
+ return c.ok(
1517
+ {
1518
+ owner,
1519
+ count: positions.length,
1520
+ positions
1521
+ },
1522
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
1523
+ cta: {
1524
+ description: "Related commands:",
1525
+ commands: firstPosition ? [
1526
+ {
1527
+ command: "cl pool",
1528
+ args: { pool: "<poolAddress>" },
1529
+ description: `Inspect pool for ${firstPosition.pair}`
1530
+ },
1531
+ {
1532
+ command: "cl quote",
1533
+ args: {
1534
+ tokenIn: firstPosition.token0.address,
1535
+ tokenOut: firstPosition.token1.address,
1536
+ amountIn: "1"
1537
+ },
1538
+ description: `Quote a ${firstPosition.token0.symbol} \u2192 ${firstPosition.token1.symbol} swap`
1539
+ }
1540
+ ] : []
1541
+ }
1542
+ }
1543
+ );
1474
1544
  }
1475
1545
  });
1476
1546
  cl.command("quote", {
@@ -1560,31 +1630,54 @@ cl.command("quote", {
1560
1630
  const inIsToken0 = normalizeAddress(inAddress) === normalizeAddress(selectedPool.token0);
1561
1631
  const poolMidPriceOutPerIn = inIsToken0 ? poolPrices.token1PerToken0 : poolPrices.token0PerToken1;
1562
1632
  const priceImpactPct = quotePriceOutPerIn === null || poolMidPriceOutPerIn === null || poolMidPriceOutPerIn === 0 ? null : finiteOrNull((poolMidPriceOutPerIn - quotePriceOutPerIn) / poolMidPriceOutPerIn * 100);
1563
- return c.ok({
1564
- pool: checksumAddress(selectedPool.pool),
1565
- selectedFee: selectedPool.fee,
1566
- selectedTickSpacing: selectedPool.tickSpacing,
1567
- tokenIn: inMeta,
1568
- tokenOut: outMeta,
1569
- amountIn: {
1570
- raw: amountInRaw.toString(),
1571
- decimal: amountInDecimal
1572
- },
1573
- amountOut: {
1574
- raw: amountOutRaw.toString(),
1575
- decimal: amountOutDecimal
1576
- },
1577
- execution: {
1578
- sqrtPriceX96After: quote[1].toString(),
1579
- initializedTicksCrossed: quote[2],
1580
- gasEstimate: quote[3].toString()
1633
+ return c.ok(
1634
+ {
1635
+ pool: checksumAddress(selectedPool.pool),
1636
+ selectedFee: selectedPool.fee,
1637
+ selectedTickSpacing: selectedPool.tickSpacing,
1638
+ tokenIn: inMeta,
1639
+ tokenOut: outMeta,
1640
+ amountIn: {
1641
+ raw: amountInRaw.toString(),
1642
+ decimal: amountInDecimal
1643
+ },
1644
+ amountOut: {
1645
+ raw: amountOutRaw.toString(),
1646
+ decimal: amountOutDecimal
1647
+ },
1648
+ execution: {
1649
+ sqrtPriceX96After: quote[1].toString(),
1650
+ initializedTicksCrossed: quote[2],
1651
+ gasEstimate: quote[3].toString()
1652
+ },
1653
+ prices: {
1654
+ poolMidPriceOutPerIn,
1655
+ quotePriceOutPerIn,
1656
+ priceImpactPct
1657
+ }
1581
1658
  },
1582
- prices: {
1583
- poolMidPriceOutPerIn,
1584
- quotePriceOutPerIn,
1585
- priceImpactPct
1659
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
1660
+ cta: {
1661
+ description: "Related commands:",
1662
+ commands: [
1663
+ {
1664
+ command: "cl pool",
1665
+ args: { pool: checksumAddress(selectedPool.pool) },
1666
+ description: "Inspect the pool used for this quote"
1667
+ },
1668
+ {
1669
+ command: "cl quote",
1670
+ args: {
1671
+ tokenIn: outMeta.address,
1672
+ tokenOut: inMeta.address,
1673
+ amountIn: amountOutDecimal
1674
+ },
1675
+ description: `Reverse quote ${outMeta.symbol} \u2192 ${inMeta.symbol}`
1676
+ }
1677
+ ]
1678
+ }
1586
1679
  }
1587
- });
1680
+ );
1588
1681
  }
1589
1682
  });
1590
1683
 
@@ -1747,10 +1840,25 @@ gauges.command("list", {
1747
1840
  periodFinishRelative: relTime(periodFinish)
1748
1841
  };
1749
1842
  });
1750
- return c.ok({
1751
- gauges: items,
1752
- count: items.length
1753
- });
1843
+ const firstGauge = items[0];
1844
+ return c.ok(
1845
+ {
1846
+ gauges: items,
1847
+ count: items.length
1848
+ },
1849
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
1850
+ cta: {
1851
+ description: "Explore gauges:",
1852
+ commands: firstGauge ? [
1853
+ {
1854
+ command: "gauges info",
1855
+ args: { gauge: firstGauge.gauge },
1856
+ description: "Inspect top gauge details"
1857
+ }
1858
+ ] : []
1859
+ }
1860
+ }
1861
+ );
1754
1862
  }
1755
1863
  });
1756
1864
  gauges.command("info", {
@@ -1877,24 +1985,46 @@ gauges.command("info", {
1877
1985
  functionName: "left"
1878
1986
  })
1879
1987
  ]);
1880
- return c.ok({
1881
- gauge: toChecksum(gauge),
1882
- pool: toChecksum(pool),
1883
- isAlive,
1884
- stakingToken: toChecksum(stakingToken),
1885
- rewardToken: toChecksum(rewardToken),
1886
- totalStaked: totalStaked.toString(),
1887
- rewardRate: rewardRate.toString(),
1888
- rewardPerTokenStored: rewardPerTokenStored.toString(),
1889
- fees0: fees0.toString(),
1890
- fees1: fees1.toString(),
1891
- left: left.toString(),
1892
- periodFinish: asNum(periodFinish),
1893
- periodFinishRelative: relTime(periodFinish),
1894
- lastUpdateTime: asNum(lastUpdateTime),
1895
- bribeContract: toChecksum(bribeContract),
1896
- feeContract: toChecksum(feeContract)
1897
- });
1988
+ return c.ok(
1989
+ {
1990
+ gauge: toChecksum(gauge),
1991
+ pool: toChecksum(pool),
1992
+ isAlive,
1993
+ stakingToken: toChecksum(stakingToken),
1994
+ rewardToken: toChecksum(rewardToken),
1995
+ totalStaked: totalStaked.toString(),
1996
+ rewardRate: rewardRate.toString(),
1997
+ rewardPerTokenStored: rewardPerTokenStored.toString(),
1998
+ fees0: fees0.toString(),
1999
+ fees1: fees1.toString(),
2000
+ left: left.toString(),
2001
+ periodFinish: asNum(periodFinish),
2002
+ periodFinishRelative: relTime(periodFinish),
2003
+ lastUpdateTime: asNum(lastUpdateTime),
2004
+ bribeContract: toChecksum(bribeContract),
2005
+ feeContract: toChecksum(feeContract)
2006
+ },
2007
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
2008
+ cta: {
2009
+ description: "Related commands:",
2010
+ commands: [
2011
+ {
2012
+ command: "ve stats",
2013
+ description: "View veABX global stats"
2014
+ },
2015
+ {
2016
+ command: "voter weights",
2017
+ description: "Check pool voting weight distribution"
2018
+ },
2019
+ {
2020
+ command: "voter bribes",
2021
+ args: { pool: toChecksum(pool) },
2022
+ description: "View bribe rewards for this pool"
2023
+ }
2024
+ ]
2025
+ }
2026
+ }
2027
+ );
1898
2028
  }
1899
2029
  });
1900
2030
  gauges.command("staked", {
@@ -1973,11 +2103,33 @@ gauges.command("staked", {
1973
2103
  staked: position.staked.toString(),
1974
2104
  earned: position.earned.toString()
1975
2105
  }));
1976
- return c.ok({
1977
- address: toChecksum(c.args.address),
1978
- positions,
1979
- count: positions.length
1980
- });
2106
+ const firstPosition = positions[0];
2107
+ return c.ok(
2108
+ {
2109
+ address: toChecksum(c.args.address),
2110
+ positions,
2111
+ count: positions.length
2112
+ },
2113
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
2114
+ cta: {
2115
+ description: "Related commands:",
2116
+ commands: [
2117
+ ...firstPosition ? [
2118
+ {
2119
+ command: "gauges info",
2120
+ args: { gauge: firstPosition.gauge },
2121
+ description: "Inspect gauge details"
2122
+ }
2123
+ ] : [],
2124
+ {
2125
+ command: "ve locks",
2126
+ args: { address: toChecksum(c.args.address) },
2127
+ description: "View veNFT locks for this address"
2128
+ }
2129
+ ]
2130
+ }
2131
+ }
2132
+ );
1981
2133
  }
1982
2134
  });
1983
2135
 
@@ -2354,12 +2506,33 @@ lending.command("markets", {
2354
2506
  const rows = markets.map((market) => toMarketRow(market.marketId, market.params, market.state, tokenMeta)).sort(
2355
2507
  (a, b) => BigInt(a.totalSupplyAssets) > BigInt(b.totalSupplyAssets) ? -1 : BigInt(a.totalSupplyAssets) < BigInt(b.totalSupplyAssets) ? 1 : 0
2356
2508
  ).slice(0, c.args.limit);
2357
- return c.ok({
2358
- morpho: toChecksum(ABOREAN_LENDING_ADDRESSES.morphoBlue),
2359
- marketCount: marketIds.length,
2360
- markets: rows,
2361
- totalsByLoanToken: summarizeByLoanToken(markets, tokenMeta)
2362
- });
2509
+ const firstMarket = rows[0];
2510
+ return c.ok(
2511
+ {
2512
+ morpho: toChecksum(ABOREAN_LENDING_ADDRESSES.morphoBlue),
2513
+ marketCount: marketIds.length,
2514
+ markets: rows,
2515
+ totalsByLoanToken: summarizeByLoanToken(markets, tokenMeta)
2516
+ },
2517
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
2518
+ cta: {
2519
+ description: "Explore lending:",
2520
+ commands: [
2521
+ ...firstMarket ? [
2522
+ {
2523
+ command: "lending market",
2524
+ args: { marketId: firstMarket.marketId },
2525
+ description: `Inspect ${firstMarket.loanToken.symbol}/${firstMarket.collateralToken.symbol} market`
2526
+ }
2527
+ ] : [],
2528
+ {
2529
+ command: "pools list",
2530
+ description: "View V2 AMM pools"
2531
+ }
2532
+ ]
2533
+ }
2534
+ }
2535
+ );
2363
2536
  }
2364
2537
  });
2365
2538
  lending.command("market", {
@@ -2401,7 +2574,26 @@ lending.command("market", {
2401
2574
  const params = normalizeMarketParams(paramsRaw);
2402
2575
  const state = normalizeMarketState(stateRaw);
2403
2576
  const tokenMeta = await readTokenMetadata2(client, [params.loanToken, params.collateralToken]);
2404
- return c.ok(toMarketRow(marketId, params, state, tokenMeta));
2577
+ const row = toMarketRow(marketId, params, state, tokenMeta);
2578
+ return c.ok(
2579
+ row,
2580
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
2581
+ cta: {
2582
+ description: "Related commands:",
2583
+ commands: [
2584
+ {
2585
+ command: "lending position",
2586
+ args: { marketId, user: "<address>" },
2587
+ description: "Inspect a user position in this market"
2588
+ },
2589
+ {
2590
+ command: "lending markets",
2591
+ description: "List all Morpho markets"
2592
+ }
2593
+ ]
2594
+ }
2595
+ }
2596
+ );
2405
2597
  }
2406
2598
  });
2407
2599
  lending.command("position", {
@@ -2508,34 +2700,52 @@ lending.command("position", {
2508
2700
  state.totalBorrowShares,
2509
2701
  state.totalBorrowAssets
2510
2702
  );
2511
- return c.ok({
2512
- marketId,
2513
- user: toChecksum(user),
2514
- loanToken: {
2515
- address: toChecksum(loanMeta.address),
2516
- symbol: loanMeta.symbol,
2517
- decimals: loanMeta.decimals
2518
- },
2519
- collateralToken: {
2520
- address: toChecksum(collateralMeta.address),
2521
- symbol: collateralMeta.symbol,
2522
- decimals: collateralMeta.decimals
2523
- },
2524
- supplyShares: position.supplyShares.toString(),
2525
- supplyAssetsEstimate: {
2526
- raw: supplyAssetsEstimate.toString(),
2527
- decimal: formatUnits2(supplyAssetsEstimate, loanMeta.decimals)
2528
- },
2529
- borrowShares: position.borrowShares.toString(),
2530
- borrowAssetsEstimate: {
2531
- raw: borrowAssetsEstimate.toString(),
2532
- decimal: formatUnits2(borrowAssetsEstimate, loanMeta.decimals)
2703
+ return c.ok(
2704
+ {
2705
+ marketId,
2706
+ user: toChecksum(user),
2707
+ loanToken: {
2708
+ address: toChecksum(loanMeta.address),
2709
+ symbol: loanMeta.symbol,
2710
+ decimals: loanMeta.decimals
2711
+ },
2712
+ collateralToken: {
2713
+ address: toChecksum(collateralMeta.address),
2714
+ symbol: collateralMeta.symbol,
2715
+ decimals: collateralMeta.decimals
2716
+ },
2717
+ supplyShares: position.supplyShares.toString(),
2718
+ supplyAssetsEstimate: {
2719
+ raw: supplyAssetsEstimate.toString(),
2720
+ decimal: formatUnits2(supplyAssetsEstimate, loanMeta.decimals)
2721
+ },
2722
+ borrowShares: position.borrowShares.toString(),
2723
+ borrowAssetsEstimate: {
2724
+ raw: borrowAssetsEstimate.toString(),
2725
+ decimal: formatUnits2(borrowAssetsEstimate, loanMeta.decimals)
2726
+ },
2727
+ collateralAssets: {
2728
+ raw: position.collateral.toString(),
2729
+ decimal: formatUnits2(BigInt(position.collateral), collateralMeta.decimals)
2730
+ }
2533
2731
  },
2534
- collateralAssets: {
2535
- raw: position.collateral.toString(),
2536
- decimal: formatUnits2(BigInt(position.collateral), collateralMeta.decimals)
2732
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
2733
+ cta: {
2734
+ description: "Related commands:",
2735
+ commands: [
2736
+ {
2737
+ command: "lending market",
2738
+ args: { marketId },
2739
+ description: "View market details"
2740
+ },
2741
+ {
2742
+ command: "lending markets",
2743
+ description: "List all Morpho markets"
2744
+ }
2745
+ ]
2746
+ }
2537
2747
  }
2538
- });
2748
+ );
2539
2749
  }
2540
2750
  });
2541
2751
 
@@ -2827,13 +3037,40 @@ pools.command("list", {
2827
3037
  client,
2828
3038
  poolStates.map((pool) => ({ pool: pool.pool, stable: pool.stable }))
2829
3039
  );
2830
- return c.ok({
2831
- total,
2832
- offset,
2833
- limit: c.options.limit,
2834
- count: poolStates.length,
2835
- pools: poolStates.map((pool, index) => toPoolSummary(pool, tokenMeta, fees[index] ?? null))
2836
- });
3040
+ const summaries = poolStates.map(
3041
+ (pool, index) => toPoolSummary(pool, tokenMeta, fees[index] ?? null)
3042
+ );
3043
+ const firstPool = summaries[0];
3044
+ return c.ok(
3045
+ {
3046
+ total,
3047
+ offset,
3048
+ limit: c.options.limit,
3049
+ count: summaries.length,
3050
+ pools: summaries
3051
+ },
3052
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3053
+ cta: {
3054
+ description: "Explore pools:",
3055
+ commands: [
3056
+ ...firstPool ? [
3057
+ {
3058
+ command: "pools pool",
3059
+ args: { address: firstPool.pool },
3060
+ description: `Inspect ${firstPool.pair}`
3061
+ }
3062
+ ] : [],
3063
+ ...firstPool ? [
3064
+ {
3065
+ command: "pools fees",
3066
+ args: { pool: firstPool.pool },
3067
+ description: `Check fees for ${firstPool.pair}`
3068
+ }
3069
+ ] : []
3070
+ ]
3071
+ }
3072
+ }
3073
+ );
2837
3074
  }
2838
3075
  });
2839
3076
  pools.command("pool", {
@@ -2896,26 +3133,50 @@ pools.command("pool", {
2896
3133
  ]);
2897
3134
  const tokenMeta = await readTokenMetadata3(client, [token0, token1]);
2898
3135
  const [fee] = await readPoolFees(client, [{ pool: poolAddress, stable }]);
2899
- return c.ok({
2900
- pool: {
2901
- ...toPoolSummary(
2902
- {
2903
- pool: poolAddress,
2904
- token0,
2905
- token1,
2906
- stable,
2907
- reserve0: reserves[0],
2908
- reserve1: reserves[1],
2909
- blockTimestampLast: reserves[2],
2910
- totalSupply
2911
- },
2912
- tokenMeta,
2913
- fee ?? null
2914
- ),
2915
- poolFees: checksumAddress4(poolFees),
2916
- factory: checksumAddress4(factory)
3136
+ const summary = toPoolSummary(
3137
+ {
3138
+ pool: poolAddress,
3139
+ token0,
3140
+ token1,
3141
+ stable,
3142
+ reserve0: reserves[0],
3143
+ reserve1: reserves[1],
3144
+ blockTimestampLast: reserves[2],
3145
+ totalSupply
3146
+ },
3147
+ tokenMeta,
3148
+ fee ?? null
3149
+ );
3150
+ return c.ok(
3151
+ {
3152
+ pool: {
3153
+ ...summary,
3154
+ poolFees: checksumAddress4(poolFees),
3155
+ factory: checksumAddress4(factory)
3156
+ }
3157
+ },
3158
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3159
+ cta: {
3160
+ description: "Next steps:",
3161
+ commands: [
3162
+ {
3163
+ command: "pools quote",
3164
+ args: {
3165
+ tokenIn: summary.token0.address,
3166
+ tokenOut: summary.token1.address,
3167
+ amountIn: "1"
3168
+ },
3169
+ description: `Quote a ${summary.token0.symbol} \u2192 ${summary.token1.symbol} swap`
3170
+ },
3171
+ {
3172
+ command: "pools fees",
3173
+ args: { pool: checksumAddress4(poolAddress) },
3174
+ description: "Check fee configuration"
3175
+ }
3176
+ ]
3177
+ }
2917
3178
  }
2918
- });
3179
+ );
2919
3180
  }
2920
3181
  });
2921
3182
  pools.command("quote", {
@@ -2994,21 +3255,44 @@ pools.command("quote", {
2994
3255
  const amountInDecimal = formatUnits3(amountInRaw, inMeta.decimals);
2995
3256
  const amountOutDecimal = formatUnits3(amountOutRaw, outMeta.decimals);
2996
3257
  const ratio = Number(amountOutDecimal) / Number(amountInDecimal);
2997
- return c.ok({
2998
- pool: checksumAddress4(poolAddress),
2999
- stable: c.options.stable,
3000
- tokenIn: inMeta,
3001
- tokenOut: outMeta,
3002
- amountIn: {
3003
- raw: amountInRaw.toString(),
3004
- decimal: amountInDecimal
3005
- },
3006
- amountOut: {
3007
- raw: amountOutRaw.toString(),
3008
- decimal: amountOutDecimal
3258
+ return c.ok(
3259
+ {
3260
+ pool: checksumAddress4(poolAddress),
3261
+ stable: c.options.stable,
3262
+ tokenIn: inMeta,
3263
+ tokenOut: outMeta,
3264
+ amountIn: {
3265
+ raw: amountInRaw.toString(),
3266
+ decimal: amountInDecimal
3267
+ },
3268
+ amountOut: {
3269
+ raw: amountOutRaw.toString(),
3270
+ decimal: amountOutDecimal
3271
+ },
3272
+ priceOutPerIn: Number(amountInDecimal) === 0 ? null : finiteOrNull3(ratio)
3009
3273
  },
3010
- priceOutPerIn: Number(amountInDecimal) === 0 ? null : finiteOrNull3(ratio)
3011
- });
3274
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3275
+ cta: {
3276
+ description: "Related commands:",
3277
+ commands: [
3278
+ {
3279
+ command: "pools pool",
3280
+ args: { address: checksumAddress4(poolAddress) },
3281
+ description: "Inspect the pool used for this quote"
3282
+ },
3283
+ {
3284
+ command: "pools quote",
3285
+ args: {
3286
+ tokenIn: outMeta.address,
3287
+ tokenOut: inMeta.address,
3288
+ amountIn: amountOutDecimal
3289
+ },
3290
+ description: `Reverse quote ${outMeta.symbol} \u2192 ${inMeta.symbol}`
3291
+ }
3292
+ ]
3293
+ }
3294
+ }
3295
+ );
3012
3296
  }
3013
3297
  });
3014
3298
  pools.command("fees", {
@@ -3060,14 +3344,37 @@ pools.command("fees", {
3060
3344
  ]);
3061
3345
  const stableFee = toFeeInfo(stableFeeRaw ?? null);
3062
3346
  const volatileFee = toFeeInfo(volatileFeeRaw ?? null);
3063
- return c.ok({
3064
- pool: checksumAddress4(pool),
3065
- pair: `${token0Meta.symbol}/${token1Meta.symbol}`,
3066
- stable,
3067
- activeFee: stable ? stableFee : volatileFee,
3068
- stableFee,
3069
- volatileFee
3070
- });
3347
+ return c.ok(
3348
+ {
3349
+ pool: checksumAddress4(pool),
3350
+ pair: `${token0Meta.symbol}/${token1Meta.symbol}`,
3351
+ stable,
3352
+ activeFee: stable ? stableFee : volatileFee,
3353
+ stableFee,
3354
+ volatileFee
3355
+ },
3356
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3357
+ cta: {
3358
+ description: "Related commands:",
3359
+ commands: [
3360
+ {
3361
+ command: "pools pool",
3362
+ args: { address: checksumAddress4(pool) },
3363
+ description: "View full pool state"
3364
+ },
3365
+ {
3366
+ command: "pools quote",
3367
+ args: {
3368
+ tokenIn: token0Meta.address,
3369
+ tokenOut: token1Meta.address,
3370
+ amountIn: "1"
3371
+ },
3372
+ description: `Quote a ${token0Meta.symbol} \u2192 ${token1Meta.symbol} swap`
3373
+ }
3374
+ ]
3375
+ }
3376
+ }
3377
+ );
3071
3378
  }
3072
3379
  });
3073
3380
 
@@ -3299,7 +3606,32 @@ vaults.command("list", {
3299
3606
  async run(c) {
3300
3607
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
3301
3608
  const snapshot = await readVaultSummary(client);
3302
- return c.ok(snapshot);
3609
+ const firstRelay = snapshot.relays[0];
3610
+ return c.ok(
3611
+ snapshot,
3612
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3613
+ cta: {
3614
+ description: "Related commands:",
3615
+ commands: [
3616
+ ...firstRelay ? [
3617
+ {
3618
+ command: "vaults relay",
3619
+ args: { relay: firstRelay.relay },
3620
+ description: `Inspect ${firstRelay.label}`
3621
+ }
3622
+ ] : [],
3623
+ {
3624
+ command: "lending markets",
3625
+ description: "View Morpho lending markets"
3626
+ },
3627
+ {
3628
+ command: "ve stats",
3629
+ description: "View veABX global stats"
3630
+ }
3631
+ ]
3632
+ }
3633
+ }
3634
+ );
3303
3635
  }
3304
3636
  });
3305
3637
  vaults.command("relay", {
@@ -3334,7 +3666,25 @@ vaults.command("relay", {
3334
3666
  }
3335
3667
  const client = createAboreanPublicClient(c.env.ABSTRACT_RPC_URL);
3336
3668
  const snapshot = await readRelaySnapshot(client, known);
3337
- return c.ok(snapshot);
3669
+ return c.ok(
3670
+ snapshot,
3671
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3672
+ cta: {
3673
+ description: "Related commands:",
3674
+ commands: [
3675
+ {
3676
+ command: "vaults list",
3677
+ description: "List all relay vaults"
3678
+ },
3679
+ {
3680
+ command: "ve lock",
3681
+ args: { tokenId: Number(snapshot.managedTokenId) },
3682
+ description: `Inspect managed veNFT #${snapshot.managedTokenId}`
3683
+ }
3684
+ ]
3685
+ }
3686
+ }
3687
+ );
3338
3688
  }
3339
3689
  });
3340
3690
 
@@ -3396,17 +3746,35 @@ ve.command("stats", {
3396
3746
  functionName: "pointHistory",
3397
3747
  args: [epoch]
3398
3748
  });
3399
- return c.ok({
3400
- token: toChecksum(token),
3401
- totalVotingPower: totalVotingPower.toString(),
3402
- totalLocked: totalLocked.toString(),
3403
- permanentLocked: permanentLocked.toString(),
3404
- epoch: asNum(epoch),
3405
- decayBias: point.bias.toString(),
3406
- decaySlope: point.slope.toString(),
3407
- lastCheckpointTimestamp: asNum(point.ts),
3408
- lastCheckpointBlock: asNum(point.blk)
3409
- });
3749
+ return c.ok(
3750
+ {
3751
+ token: toChecksum(token),
3752
+ totalVotingPower: totalVotingPower.toString(),
3753
+ totalLocked: totalLocked.toString(),
3754
+ permanentLocked: permanentLocked.toString(),
3755
+ epoch: asNum(epoch),
3756
+ decayBias: point.bias.toString(),
3757
+ decaySlope: point.slope.toString(),
3758
+ lastCheckpointTimestamp: asNum(point.ts),
3759
+ lastCheckpointBlock: asNum(point.blk)
3760
+ },
3761
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3762
+ cta: {
3763
+ description: "Explore veABX:",
3764
+ commands: [
3765
+ {
3766
+ command: "ve locks",
3767
+ args: { address: "<owner>" },
3768
+ description: "List veNFT locks for an address"
3769
+ },
3770
+ {
3771
+ command: "voter epoch",
3772
+ description: "View current emissions epoch timing"
3773
+ }
3774
+ ]
3775
+ }
3776
+ }
3777
+ );
3410
3778
  }
3411
3779
  });
3412
3780
  ve.command("lock", {
@@ -3447,14 +3815,33 @@ ve.command("lock", {
3447
3815
  args: [tokenId]
3448
3816
  })
3449
3817
  ]);
3450
- return c.ok({
3451
- tokenId: c.args.tokenId,
3452
- owner: toChecksum(owner),
3453
- amount: locked.amount.toString(),
3454
- unlockTime: asNum(locked.end),
3455
- isPermanent: locked.isPermanent,
3456
- votingPower: votingPower.toString()
3457
- });
3818
+ return c.ok(
3819
+ {
3820
+ tokenId: c.args.tokenId,
3821
+ owner: toChecksum(owner),
3822
+ amount: locked.amount.toString(),
3823
+ unlockTime: asNum(locked.end),
3824
+ isPermanent: locked.isPermanent,
3825
+ votingPower: votingPower.toString()
3826
+ },
3827
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3828
+ cta: {
3829
+ description: "Related commands:",
3830
+ commands: [
3831
+ {
3832
+ command: "ve voting-power",
3833
+ args: { tokenId: c.args.tokenId },
3834
+ description: "Check current voting power"
3835
+ },
3836
+ {
3837
+ command: "voter rewards",
3838
+ args: { tokenId: c.args.tokenId },
3839
+ description: "Check claimable rewards for this veNFT"
3840
+ }
3841
+ ]
3842
+ }
3843
+ }
3844
+ );
3458
3845
  }
3459
3846
  });
3460
3847
  ve.command("locks", {
@@ -3537,11 +3924,31 @@ ve.command("locks", {
3537
3924
  votingPower: votingPower.toString()
3538
3925
  };
3539
3926
  });
3540
- return c.ok({
3541
- address: toChecksum(c.args.address),
3542
- locks,
3543
- count: locks.length
3544
- });
3927
+ const firstLock = locks[0];
3928
+ return c.ok(
3929
+ {
3930
+ address: toChecksum(c.args.address),
3931
+ locks,
3932
+ count: locks.length
3933
+ },
3934
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3935
+ cta: {
3936
+ description: "Explore locks:",
3937
+ commands: firstLock ? [
3938
+ {
3939
+ command: "ve lock",
3940
+ args: { tokenId: Number(firstLock.tokenId) },
3941
+ description: `Inspect veNFT #${firstLock.tokenId}`
3942
+ },
3943
+ {
3944
+ command: "voter rewards",
3945
+ args: { tokenId: Number(firstLock.tokenId) },
3946
+ description: `Check rewards for veNFT #${firstLock.tokenId}`
3947
+ }
3948
+ ] : []
3949
+ }
3950
+ }
3951
+ );
3545
3952
  }
3546
3953
  });
3547
3954
  ve.command("voting-power", {
@@ -3563,10 +3970,29 @@ ve.command("voting-power", {
3563
3970
  functionName: "balanceOfNFT",
3564
3971
  args: [BigInt(c.args.tokenId)]
3565
3972
  });
3566
- return c.ok({
3567
- tokenId: c.args.tokenId,
3568
- votingPower: votingPower.toString()
3569
- });
3973
+ return c.ok(
3974
+ {
3975
+ tokenId: c.args.tokenId,
3976
+ votingPower: votingPower.toString()
3977
+ },
3978
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
3979
+ cta: {
3980
+ description: "Related commands:",
3981
+ commands: [
3982
+ {
3983
+ command: "ve lock",
3984
+ args: { tokenId: c.args.tokenId },
3985
+ description: "View full lock details"
3986
+ },
3987
+ {
3988
+ command: "voter rewards",
3989
+ args: { tokenId: c.args.tokenId },
3990
+ description: "Check claimable rewards"
3991
+ }
3992
+ ]
3993
+ }
3994
+ }
3995
+ );
3570
3996
  }
3571
3997
  });
3572
3998
 
@@ -3654,15 +4080,32 @@ voter.command("epoch", {
3654
4080
  ]);
3655
4081
  const now = Math.floor(Date.now() / 1e3);
3656
4082
  const epochEnd = asNum(activePeriod + weekSeconds);
3657
- return c.ok({
3658
- activePeriod: asNum(activePeriod),
3659
- epochEnd,
3660
- secondsRemaining: clampPositive(epochEnd - now),
3661
- timeRemaining: relTime(activePeriod + weekSeconds),
3662
- weekSeconds: asNum(weekSeconds),
3663
- epochCount: asNum(epochCount),
3664
- weeklyEmission: weeklyEmission.toString()
3665
- });
4083
+ return c.ok(
4084
+ {
4085
+ activePeriod: asNum(activePeriod),
4086
+ epochEnd,
4087
+ secondsRemaining: clampPositive(epochEnd - now),
4088
+ timeRemaining: relTime(activePeriod + weekSeconds),
4089
+ weekSeconds: asNum(weekSeconds),
4090
+ epochCount: asNum(epochCount),
4091
+ weeklyEmission: weeklyEmission.toString()
4092
+ },
4093
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
4094
+ cta: {
4095
+ description: "Related commands:",
4096
+ commands: [
4097
+ {
4098
+ command: "voter weights",
4099
+ description: "View pool voting weight distribution"
4100
+ },
4101
+ {
4102
+ command: "gauges list",
4103
+ description: "List active gauges"
4104
+ }
4105
+ ]
4106
+ }
4107
+ }
4108
+ );
3666
4109
  }
3667
4110
  });
3668
4111
  voter.command("weights", {
@@ -3726,11 +4169,32 @@ voter.command("weights", {
3726
4169
  gauge: toChecksum(entry.gauge),
3727
4170
  weight: entry.weight.toString()
3728
4171
  }));
3729
- return c.ok({
3730
- totalWeight: totalWeight.toString(),
3731
- pools: entries,
3732
- count: entries.length
3733
- });
4172
+ const firstEntry = entries[0];
4173
+ return c.ok(
4174
+ {
4175
+ totalWeight: totalWeight.toString(),
4176
+ pools: entries,
4177
+ count: entries.length
4178
+ },
4179
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
4180
+ cta: {
4181
+ description: "Related commands:",
4182
+ commands: [
4183
+ {
4184
+ command: "voter epoch",
4185
+ description: "View current epoch timing"
4186
+ },
4187
+ ...firstEntry ? [
4188
+ {
4189
+ command: "voter bribes",
4190
+ args: { pool: firstEntry.pool },
4191
+ description: "View bribe rewards for top-weighted pool"
4192
+ }
4193
+ ] : []
4194
+ ]
4195
+ }
4196
+ }
4197
+ );
3734
4198
  }
3735
4199
  });
3736
4200
  voter.command("rewards", {
@@ -3802,16 +4266,34 @@ voter.command("rewards", {
3802
4266
  args: [tokenId]
3803
4267
  })
3804
4268
  ]);
3805
- return c.ok({
3806
- tokenId: c.args.tokenId,
3807
- rewardToken: toChecksum(rewardToken),
3808
- claimableRebase: claimableRebase.toString(),
3809
- timeCursor: asNum(timeCursor),
3810
- lastTokenTime: asNum(lastTokenTime),
3811
- distributorStartTime: asNum(distributorStartTime),
3812
- usedWeight: usedWeight.toString(),
3813
- lastVoted: asNum(lastVoted)
3814
- });
4269
+ return c.ok(
4270
+ {
4271
+ tokenId: c.args.tokenId,
4272
+ rewardToken: toChecksum(rewardToken),
4273
+ claimableRebase: claimableRebase.toString(),
4274
+ timeCursor: asNum(timeCursor),
4275
+ lastTokenTime: asNum(lastTokenTime),
4276
+ distributorStartTime: asNum(distributorStartTime),
4277
+ usedWeight: usedWeight.toString(),
4278
+ lastVoted: asNum(lastVoted)
4279
+ },
4280
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
4281
+ cta: {
4282
+ description: "Related commands:",
4283
+ commands: [
4284
+ {
4285
+ command: "ve lock",
4286
+ args: { tokenId: c.args.tokenId },
4287
+ description: "View lock details for this veNFT"
4288
+ },
4289
+ {
4290
+ command: "voter weights",
4291
+ description: "Check pool voting weight distribution"
4292
+ }
4293
+ ]
4294
+ }
4295
+ }
4296
+ );
3815
4297
  }
3816
4298
  });
3817
4299
  voter.command("bribes", {
@@ -3916,14 +4398,32 @@ voter.command("bribes", {
3916
4398
  token: toChecksum(token),
3917
4399
  epochAmount: epochAmounts[index].toString()
3918
4400
  }));
3919
- return c.ok({
3920
- pool: toChecksum(c.args.pool),
3921
- gauge: toChecksum(gauge),
3922
- bribeContract: toChecksum(bribeContract),
3923
- epochStart: asNum(epochStart),
3924
- rewardTokens: items,
3925
- count: items.length
3926
- });
4401
+ return c.ok(
4402
+ {
4403
+ pool: toChecksum(c.args.pool),
4404
+ gauge: toChecksum(gauge),
4405
+ bribeContract: toChecksum(bribeContract),
4406
+ epochStart: asNum(epochStart),
4407
+ rewardTokens: items,
4408
+ count: items.length
4409
+ },
4410
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
4411
+ cta: {
4412
+ description: "Related commands:",
4413
+ commands: [
4414
+ {
4415
+ command: "gauges info",
4416
+ args: { gauge: toChecksum(gauge) },
4417
+ description: "Inspect gauge details"
4418
+ },
4419
+ {
4420
+ command: "voter epoch",
4421
+ description: "View current epoch timing"
4422
+ }
4423
+ ]
4424
+ }
4425
+ }
4426
+ );
3927
4427
  }
3928
4428
  });
3929
4429
 
@@ -4430,38 +4930,63 @@ cli.command("status", {
4430
4930
  }
4431
4931
  const now = Math.floor(Date.now() / 1e3);
4432
4932
  const epochEnd = Number(activePeriod) + Number(weekSeconds);
4433
- return c.ok({
4434
- v2PoolCount: Number(v2PoolCount),
4435
- clPoolCount: Number(clPoolCount),
4436
- gaugeCount: Number(gaugeCount),
4437
- totalVotingWeight: String(totalVotingWeight),
4438
- veABXTotalSupply: String(veABXTotalSupply),
4439
- veABXLockedSupply: String(veABXLockedSupply),
4440
- epoch: {
4441
- activePeriod: Number(activePeriod),
4442
- epochEnd,
4443
- secondsRemaining: Math.max(0, epochEnd - now),
4444
- epochCount: Number(epochCount),
4445
- weeklyEmission: String(weeklyEmission)
4446
- },
4447
- topPools: v2PoolSnapshot.topPools,
4448
- tvl: {
4449
- v2ReserveUnitEstimate: v2PoolSnapshot.reserveUnitTvl,
4450
- vaultManagedVotingPower
4451
- },
4452
- vaults: {
4453
- relayCount: vaultRelayCount,
4454
- managedVotingPower: vaultManagedVotingPower,
4455
- note: vaultNote
4933
+ return c.ok(
4934
+ {
4935
+ v2PoolCount: Number(v2PoolCount),
4936
+ clPoolCount: Number(clPoolCount),
4937
+ gaugeCount: Number(gaugeCount),
4938
+ totalVotingWeight: String(totalVotingWeight),
4939
+ veABXTotalSupply: String(veABXTotalSupply),
4940
+ veABXLockedSupply: String(veABXLockedSupply),
4941
+ epoch: {
4942
+ activePeriod: Number(activePeriod),
4943
+ epochEnd,
4944
+ secondsRemaining: Math.max(0, epochEnd - now),
4945
+ epochCount: Number(epochCount),
4946
+ weeklyEmission: String(weeklyEmission)
4947
+ },
4948
+ topPools: v2PoolSnapshot.topPools,
4949
+ tvl: {
4950
+ v2ReserveUnitEstimate: v2PoolSnapshot.reserveUnitTvl,
4951
+ vaultManagedVotingPower
4952
+ },
4953
+ vaults: {
4954
+ relayCount: vaultRelayCount,
4955
+ managedVotingPower: vaultManagedVotingPower,
4956
+ note: vaultNote
4957
+ },
4958
+ lending: {
4959
+ available: lendingAvailable,
4960
+ morpho: lendingMorpho,
4961
+ marketCount: lendingMarketCount,
4962
+ supplyByLoanToken: lendingSupplyByLoanToken,
4963
+ note: lendingNote
4964
+ }
4456
4965
  },
4457
- lending: {
4458
- available: lendingAvailable,
4459
- morpho: lendingMorpho,
4460
- marketCount: lendingMarketCount,
4461
- supplyByLoanToken: lendingSupplyByLoanToken,
4462
- note: lendingNote
4966
+ c.format === "json" || c.format === "jsonl" ? void 0 : {
4967
+ cta: {
4968
+ description: "Drill down:",
4969
+ commands: [
4970
+ {
4971
+ command: "pools list",
4972
+ description: "List V2 AMM pools"
4973
+ },
4974
+ {
4975
+ command: "cl pools",
4976
+ description: "List Slipstream CL pools"
4977
+ },
4978
+ {
4979
+ command: "gauges list",
4980
+ description: "List active gauges"
4981
+ },
4982
+ {
4983
+ command: "ve stats",
4984
+ description: "View veABX global stats"
4985
+ }
4986
+ ]
4987
+ }
4463
4988
  }
4464
- });
4989
+ );
4465
4990
  }
4466
4991
  });
4467
4992
  applyFriendlyErrorHandling(cli);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectratools/aborean-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "CLI for Aborean Finance DEX on Abstract (pools, swaps, gauges, voting escrow).",
5
5
  "type": "module",
6
6
  "license": "MIT",