@hypurrquant/defi-cli 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/main.js +232 -20
- package/dist/main.js.map +1 -1
- package/dist/mcp-server.js +23 -15
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
+
import { createRequire } from "module";
|
|
5
6
|
|
|
6
7
|
// src/executor.ts
|
|
7
8
|
import { createPublicClient as createPublicClient2, createWalletClient, http as http2 } from "viem";
|
|
@@ -863,6 +864,10 @@ async function multicallRead(rpcUrl, calls) {
|
|
|
863
864
|
});
|
|
864
865
|
return decoded.map((r) => r.success ? r.returnData : null);
|
|
865
866
|
}
|
|
867
|
+
function decodeU256(data) {
|
|
868
|
+
if (!data || data.length < 66) return 0n;
|
|
869
|
+
return BigInt(data.slice(0, 66));
|
|
870
|
+
}
|
|
866
871
|
var ChainConfig = class {
|
|
867
872
|
name;
|
|
868
873
|
chain_id;
|
|
@@ -6120,7 +6125,7 @@ var POOL_ABI4 = parseAbi27([
|
|
|
6120
6125
|
var ORACLE_ABI5 = parseAbi27([
|
|
6121
6126
|
"function getAssetPrice(address asset) external view returns (uint256)"
|
|
6122
6127
|
]);
|
|
6123
|
-
function
|
|
6128
|
+
function decodeU2562(data, wordOffset = 0) {
|
|
6124
6129
|
if (!data || data.length < 2 + (wordOffset + 1) * 64) return 0n;
|
|
6125
6130
|
const hex = data.slice(2 + wordOffset * 64, 2 + wordOffset * 64 + 64);
|
|
6126
6131
|
return BigInt("0x" + hex);
|
|
@@ -6200,7 +6205,7 @@ function registerPortfolio(parent, getOpts) {
|
|
|
6200
6205
|
let nativePriceUsd = 0;
|
|
6201
6206
|
if (oracleAddr) {
|
|
6202
6207
|
const priceData = results[results.length - 1] ?? null;
|
|
6203
|
-
nativePriceUsd = Number(
|
|
6208
|
+
nativePriceUsd = Number(decodeU2562(priceData)) / 1e8;
|
|
6204
6209
|
}
|
|
6205
6210
|
let totalValueUsd = 0;
|
|
6206
6211
|
let idx = 0;
|
|
@@ -6214,7 +6219,7 @@ function registerPortfolio(parent, getOpts) {
|
|
|
6214
6219
|
}
|
|
6215
6220
|
if (entry.address === "0x0000000000000000000000000000000000000000") continue;
|
|
6216
6221
|
if (idx >= results.length) break;
|
|
6217
|
-
const balance =
|
|
6222
|
+
const balance = decodeU2562(results[idx] ?? null);
|
|
6218
6223
|
if (balance > 0n) {
|
|
6219
6224
|
const decimals = entry.decimals;
|
|
6220
6225
|
const balF64 = Number(balance) / 10 ** decimals;
|
|
@@ -6234,9 +6239,9 @@ function registerPortfolio(parent, getOpts) {
|
|
|
6234
6239
|
if (idx >= results.length) break;
|
|
6235
6240
|
const data = results[idx] ?? null;
|
|
6236
6241
|
if (data && data.length >= 2 + 192 * 2) {
|
|
6237
|
-
const collateral = Number(
|
|
6238
|
-
const debt = Number(
|
|
6239
|
-
const hfRaw =
|
|
6242
|
+
const collateral = Number(decodeU2562(data, 0)) / 1e8;
|
|
6243
|
+
const debt = Number(decodeU2562(data, 1)) / 1e8;
|
|
6244
|
+
const hfRaw = decodeU2562(data, 5);
|
|
6240
6245
|
let hf = null;
|
|
6241
6246
|
if (hfRaw <= BigInt("0xffffffffffffffffffffffffffffffff")) {
|
|
6242
6247
|
const v = Number(hfRaw) / 1e18;
|
|
@@ -7078,7 +7083,7 @@ function estimateTokenValue(symbol, balance, nativePrice) {
|
|
|
7078
7083
|
if (["WETH", "ETH", "METH", "CBETH", "WSTETH"].includes(s)) return balance * 2350;
|
|
7079
7084
|
return balance * nativePrice;
|
|
7080
7085
|
}
|
|
7081
|
-
function
|
|
7086
|
+
function decodeU2563(data, offset = 0) {
|
|
7082
7087
|
if (!data || data.length < 2 + (offset + 32) * 2) return 0n;
|
|
7083
7088
|
const hex = data.slice(2 + offset * 64, 2 + offset * 64 + 64);
|
|
7084
7089
|
return BigInt("0x" + hex);
|
|
@@ -7116,7 +7121,7 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
|
|
|
7116
7121
|
} catch {
|
|
7117
7122
|
return null;
|
|
7118
7123
|
}
|
|
7119
|
-
const nativePrice = oracleAddr ? Number(
|
|
7124
|
+
const nativePrice = oracleAddr ? Number(decodeU2563(results[results.length - 1])) / 1e8 : 0;
|
|
7120
7125
|
const tokenBalances = [];
|
|
7121
7126
|
const lendingPositions = [];
|
|
7122
7127
|
let chainValue = 0;
|
|
@@ -7126,7 +7131,7 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
|
|
|
7126
7131
|
const ct = callTypes[i];
|
|
7127
7132
|
const data = results[i] ?? null;
|
|
7128
7133
|
if (ct.kind === "token") {
|
|
7129
|
-
const balance =
|
|
7134
|
+
const balance = decodeU2563(data);
|
|
7130
7135
|
if (balance > 0n) {
|
|
7131
7136
|
const balF64 = Number(balance) / 10 ** ct.decimals;
|
|
7132
7137
|
const valueUsd = estimateTokenValue(ct.symbol, balF64, nativePrice);
|
|
@@ -7143,9 +7148,9 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
|
|
|
7143
7148
|
if (data && data.length >= 2 + 192 * 2) {
|
|
7144
7149
|
const priceDecimals = ct.iface === "aave_v2" ? 18 : 8;
|
|
7145
7150
|
const divisor = 10 ** priceDecimals;
|
|
7146
|
-
const collateral = Number(
|
|
7147
|
-
const debt = Number(
|
|
7148
|
-
const hfRaw =
|
|
7151
|
+
const collateral = Number(decodeU2563(data, 0)) / divisor;
|
|
7152
|
+
const debt = Number(decodeU2563(data, 1)) / divisor;
|
|
7153
|
+
const hfRaw = decodeU2563(data, 5);
|
|
7149
7154
|
let hf = null;
|
|
7150
7155
|
if (hfRaw <= BigInt("0xffffffffffffffffffffffffffffffff")) {
|
|
7151
7156
|
const v = Number(hfRaw) / 1e18;
|
|
@@ -7491,7 +7496,7 @@ function round24(x) {
|
|
|
7491
7496
|
function round43(x) {
|
|
7492
7497
|
return Math.round(x * 1e4) / 1e4;
|
|
7493
7498
|
}
|
|
7494
|
-
function
|
|
7499
|
+
function decodeU2564(data, wordOffset = 0) {
|
|
7495
7500
|
if (!data || data.length < 2 + (wordOffset + 1) * 64) return 0n;
|
|
7496
7501
|
const hex = data.slice(2 + wordOffset * 64, 2 + wordOffset * 64 + 64);
|
|
7497
7502
|
return BigInt("0x" + hex);
|
|
@@ -7616,9 +7621,9 @@ function registerWhales(parent, getOpts) {
|
|
|
7616
7621
|
if (data && data.length >= 2 + 192 * 2) {
|
|
7617
7622
|
const dec = iface === "aave_v2" ? 18 : 8;
|
|
7618
7623
|
const divisor = 10 ** dec;
|
|
7619
|
-
const collateral = Number(
|
|
7620
|
-
const debt = Number(
|
|
7621
|
-
const hfRaw =
|
|
7624
|
+
const collateral = Number(decodeU2564(data, 0)) / divisor;
|
|
7625
|
+
const debt = Number(decodeU2564(data, 1)) / divisor;
|
|
7626
|
+
const hfRaw = decodeU2564(data, 5);
|
|
7622
7627
|
let hf = null;
|
|
7623
7628
|
if (hfRaw <= BigInt("0xffffffffffffffffffffffffffffffff")) {
|
|
7624
7629
|
const v = Number(hfRaw) / 1e18;
|
|
@@ -8021,11 +8026,11 @@ function registerBridge(parent, getOpts) {
|
|
|
8021
8026
|
const amountUsdc = Number(BigInt(opts.amount)) / 1e6;
|
|
8022
8027
|
const { fee, maxFeeSubunits } = await getCctpFeeEstimate(srcDomain, dstDomain, amountUsdc);
|
|
8023
8028
|
const recipientPadded = `0x${"0".repeat(24)}${recipient.replace("0x", "").toLowerCase()}`;
|
|
8024
|
-
const { encodeFunctionData:
|
|
8025
|
-
const tokenMessengerAbi =
|
|
8029
|
+
const { encodeFunctionData: encodeFunctionData29, parseAbi: parseAbi33 } = await import("viem");
|
|
8030
|
+
const tokenMessengerAbi = parseAbi33([
|
|
8026
8031
|
"function depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller, uint256 maxFee, uint32 minFinalityThreshold) external returns (uint64 nonce)"
|
|
8027
8032
|
]);
|
|
8028
|
-
const data =
|
|
8033
|
+
const data = encodeFunctionData29({
|
|
8029
8034
|
abi: tokenMessengerAbi,
|
|
8030
8035
|
functionName: "depositForBurn",
|
|
8031
8036
|
args: [
|
|
@@ -8219,6 +8224,8 @@ function registerFarm(parent, getOpts, makeExecutor2) {
|
|
|
8219
8224
|
}
|
|
8220
8225
|
|
|
8221
8226
|
// src/cli.ts
|
|
8227
|
+
var _require = createRequire(import.meta.url);
|
|
8228
|
+
var _pkg = _require("../package.json");
|
|
8222
8229
|
var BANNER = `
|
|
8223
8230
|
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557
|
|
8224
8231
|
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551
|
|
@@ -8232,7 +8239,7 @@ var BANNER = `
|
|
|
8232
8239
|
Scan exploits, swap tokens, bridge assets, track whales,
|
|
8233
8240
|
compare yields \u2014 all from your terminal.
|
|
8234
8241
|
`;
|
|
8235
|
-
var program = new Command().name("defi").description("DeFi CLI \u2014 Multi-chain DeFi toolkit").version(
|
|
8242
|
+
var program = new Command().name("defi").description("DeFi CLI \u2014 Multi-chain DeFi toolkit").version(_pkg.version).addHelpText("before", BANNER).option("--json", "Output as JSON").option("--ndjson", "Output as newline-delimited JSON").option("--fields <fields>", "Select specific output fields (comma-separated)").option("--chain <chain>", "Target chain", "hyperevm").option("--dry-run", "Dry-run mode (default, no broadcast)", true).option("--broadcast", "Actually broadcast the transaction");
|
|
8236
8243
|
function getOutputMode() {
|
|
8237
8244
|
const opts = program.opts();
|
|
8238
8245
|
return parseOutputMode(opts);
|
|
@@ -8274,9 +8281,214 @@ program.command("agent").description("Agent mode: read JSON commands from stdin
|
|
|
8274
8281
|
process.exit(1);
|
|
8275
8282
|
});
|
|
8276
8283
|
|
|
8284
|
+
// src/landing.ts
|
|
8285
|
+
import pc2 from "picocolors";
|
|
8286
|
+
import { encodeFunctionData as encodeFunctionData28, parseAbi as parseAbi31, formatUnits } from "viem";
|
|
8287
|
+
var HYPEREVM_DISPLAY = ["HYPE", "WHYPE", "USDC", "USDT0", "USDe", "kHYPE", "wstHYPE"];
|
|
8288
|
+
var MANTLE_DISPLAY = ["MNT", "WMNT", "USDC", "USDT", "WETH", "mETH"];
|
|
8289
|
+
var balanceOfAbi = parseAbi31([
|
|
8290
|
+
"function balanceOf(address account) view returns (uint256)"
|
|
8291
|
+
]);
|
|
8292
|
+
var getEthBalanceAbi = parseAbi31([
|
|
8293
|
+
"function getEthBalance(address addr) view returns (uint256)"
|
|
8294
|
+
]);
|
|
8295
|
+
async function fetchBalances(rpcUrl, wallet, tokens) {
|
|
8296
|
+
const calls = tokens.map((t) => {
|
|
8297
|
+
const isNative = t.tags?.includes("native") || t.address === "0x0000000000000000000000000000000000000000";
|
|
8298
|
+
if (isNative) {
|
|
8299
|
+
return [
|
|
8300
|
+
MULTICALL3_ADDRESS,
|
|
8301
|
+
encodeFunctionData28({
|
|
8302
|
+
abi: getEthBalanceAbi,
|
|
8303
|
+
functionName: "getEthBalance",
|
|
8304
|
+
args: [wallet]
|
|
8305
|
+
})
|
|
8306
|
+
];
|
|
8307
|
+
}
|
|
8308
|
+
return [
|
|
8309
|
+
t.address,
|
|
8310
|
+
encodeFunctionData28({
|
|
8311
|
+
abi: balanceOfAbi,
|
|
8312
|
+
functionName: "balanceOf",
|
|
8313
|
+
args: [wallet]
|
|
8314
|
+
})
|
|
8315
|
+
];
|
|
8316
|
+
});
|
|
8317
|
+
let results;
|
|
8318
|
+
try {
|
|
8319
|
+
results = await multicallRead(rpcUrl, calls);
|
|
8320
|
+
} catch {
|
|
8321
|
+
results = tokens.map(() => null);
|
|
8322
|
+
}
|
|
8323
|
+
return tokens.map((t, i) => {
|
|
8324
|
+
const raw = decodeU256(results[i]);
|
|
8325
|
+
const formatted = formatUnits(raw, t.decimals);
|
|
8326
|
+
const num = parseFloat(formatted);
|
|
8327
|
+
const display = num === 0 ? "0.00" : num >= 1e3 ? num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 6 });
|
|
8328
|
+
return { symbol: t.symbol, balance: display, decimals: t.decimals };
|
|
8329
|
+
});
|
|
8330
|
+
}
|
|
8331
|
+
function shortenAddress(addr) {
|
|
8332
|
+
if (addr.length < 12) return addr;
|
|
8333
|
+
return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
|
|
8334
|
+
}
|
|
8335
|
+
function padRight(s, len) {
|
|
8336
|
+
return s.length >= len ? s : s + " ".repeat(len - s.length);
|
|
8337
|
+
}
|
|
8338
|
+
function padLeft(s, len) {
|
|
8339
|
+
return s.length >= len ? s : " ".repeat(len - s.length) + s;
|
|
8340
|
+
}
|
|
8341
|
+
function formatBalanceLine(sym, bal) {
|
|
8342
|
+
const symPad = padRight(sym, 10);
|
|
8343
|
+
const balPad = padLeft(bal, 12);
|
|
8344
|
+
return ` ${symPad}${balPad}`;
|
|
8345
|
+
}
|
|
8346
|
+
async function showLandingPage(isJson) {
|
|
8347
|
+
const registry = Registry.loadEmbedded();
|
|
8348
|
+
const wallet = process.env.DEFI_WALLET_ADDRESS;
|
|
8349
|
+
if (isJson) {
|
|
8350
|
+
if (!wallet) {
|
|
8351
|
+
console.log(JSON.stringify({ error: "DEFI_WALLET_ADDRESS not set" }, null, 2));
|
|
8352
|
+
return;
|
|
8353
|
+
}
|
|
8354
|
+
const heChain2 = registry.getChain("hyperevm");
|
|
8355
|
+
const mantleChain2 = registry.getChain("mantle");
|
|
8356
|
+
const heTokens2 = (registry.tokens.get("hyperevm") ?? []).filter((t) => HYPEREVM_DISPLAY.includes(t.symbol));
|
|
8357
|
+
const mantleTokens2 = (registry.tokens.get("mantle") ?? []).filter((t) => MANTLE_DISPLAY.includes(t.symbol));
|
|
8358
|
+
const heSorted2 = HYPEREVM_DISPLAY.map((s) => heTokens2.find((t) => t.symbol === s)).filter(Boolean);
|
|
8359
|
+
const mantleSorted2 = MANTLE_DISPLAY.map((s) => mantleTokens2.find((t) => t.symbol === s)).filter(Boolean);
|
|
8360
|
+
const [heBalances2, mantleBalances2] = await Promise.all([
|
|
8361
|
+
fetchBalances(heChain2.effectiveRpcUrl(), wallet, heSorted2),
|
|
8362
|
+
fetchBalances(mantleChain2.effectiveRpcUrl(), wallet, mantleSorted2)
|
|
8363
|
+
]);
|
|
8364
|
+
console.log(JSON.stringify({
|
|
8365
|
+
wallet,
|
|
8366
|
+
chains: {
|
|
8367
|
+
hyperevm: { name: heChain2.name, balances: heBalances2 },
|
|
8368
|
+
mantle: { name: mantleChain2.name, balances: mantleBalances2 }
|
|
8369
|
+
}
|
|
8370
|
+
}, null, 2));
|
|
8371
|
+
return;
|
|
8372
|
+
}
|
|
8373
|
+
const { createRequire: createRequire2 } = await import("module");
|
|
8374
|
+
const _require2 = createRequire2(import.meta.url);
|
|
8375
|
+
const pkg = _require2("../package.json");
|
|
8376
|
+
const version = pkg.version;
|
|
8377
|
+
if (!wallet) {
|
|
8378
|
+
console.log("");
|
|
8379
|
+
console.log(pc2.bold(pc2.cyan(" DeFi CLI v" + version)));
|
|
8380
|
+
console.log("");
|
|
8381
|
+
console.log(pc2.yellow(" Wallet not configured."));
|
|
8382
|
+
console.log(" Set DEFI_WALLET_ADDRESS to see your balances:");
|
|
8383
|
+
console.log("");
|
|
8384
|
+
console.log(pc2.dim(" export DEFI_WALLET_ADDRESS=0x..."));
|
|
8385
|
+
console.log("");
|
|
8386
|
+
console.log(" Commands:");
|
|
8387
|
+
console.log(pc2.dim(" defi status Protocol overview"));
|
|
8388
|
+
console.log(pc2.dim(" defi lending rates Compare lending APYs"));
|
|
8389
|
+
console.log(pc2.dim(" defi dex quote Get swap quotes"));
|
|
8390
|
+
console.log(pc2.dim(" defi portfolio View all positions"));
|
|
8391
|
+
console.log(pc2.dim(" defi scan Exploit detection"));
|
|
8392
|
+
console.log(pc2.dim(" defi --help Full command list"));
|
|
8393
|
+
console.log("");
|
|
8394
|
+
return;
|
|
8395
|
+
}
|
|
8396
|
+
const heChain = registry.getChain("hyperevm");
|
|
8397
|
+
const mantleChain = registry.getChain("mantle");
|
|
8398
|
+
const heTokens = (registry.tokens.get("hyperevm") ?? []).filter((t) => HYPEREVM_DISPLAY.includes(t.symbol));
|
|
8399
|
+
const mantleTokens = (registry.tokens.get("mantle") ?? []).filter((t) => MANTLE_DISPLAY.includes(t.symbol));
|
|
8400
|
+
const heSorted = HYPEREVM_DISPLAY.map((s) => heTokens.find((t) => t.symbol === s)).filter(Boolean);
|
|
8401
|
+
const mantleSorted = MANTLE_DISPLAY.map((s) => mantleTokens.find((t) => t.symbol === s)).filter(Boolean);
|
|
8402
|
+
const [heBalances, mantleBalances] = await Promise.all([
|
|
8403
|
+
fetchBalances(heChain.effectiveRpcUrl(), wallet, heSorted).catch(
|
|
8404
|
+
() => heSorted.map((t) => ({ symbol: t.symbol, balance: "?", decimals: t.decimals }))
|
|
8405
|
+
),
|
|
8406
|
+
fetchBalances(mantleChain.effectiveRpcUrl(), wallet, mantleSorted).catch(
|
|
8407
|
+
() => mantleSorted.map((t) => ({ symbol: t.symbol, balance: "?", decimals: t.decimals }))
|
|
8408
|
+
)
|
|
8409
|
+
]);
|
|
8410
|
+
const colWidth = 38;
|
|
8411
|
+
const divider = "\u2500".repeat(colWidth - 2);
|
|
8412
|
+
console.log("");
|
|
8413
|
+
console.log(
|
|
8414
|
+
pc2.bold(pc2.cyan(" DeFi CLI v" + version)) + pc2.dim(" \u2014 ") + pc2.bold(heChain.name) + pc2.dim(" \xB7 ") + pc2.bold(mantleChain.name)
|
|
8415
|
+
);
|
|
8416
|
+
console.log("");
|
|
8417
|
+
console.log(" Wallet: " + pc2.yellow(shortenAddress(wallet)));
|
|
8418
|
+
console.log("");
|
|
8419
|
+
const heHeader = padRight(
|
|
8420
|
+
" " + pc2.bold(heChain.name),
|
|
8421
|
+
colWidth + 10
|
|
8422
|
+
/* account for ANSI */
|
|
8423
|
+
);
|
|
8424
|
+
const mantleHeader = pc2.bold(mantleChain.name);
|
|
8425
|
+
console.log(heHeader + " " + mantleHeader);
|
|
8426
|
+
const heDivider = padRight(" " + pc2.dim(divider), colWidth + 10);
|
|
8427
|
+
const mantleDivider = pc2.dim(divider);
|
|
8428
|
+
console.log(heDivider + " " + mantleDivider);
|
|
8429
|
+
const maxRows = Math.max(heBalances.length, mantleBalances.length);
|
|
8430
|
+
for (let i = 0; i < maxRows; i++) {
|
|
8431
|
+
const heEntry = heBalances[i];
|
|
8432
|
+
const mantleEntry = mantleBalances[i];
|
|
8433
|
+
const heText = heEntry ? formatBalanceLine(heEntry.symbol, heEntry.balance) : "";
|
|
8434
|
+
const mantleText = mantleEntry ? formatBalanceLine(mantleEntry.symbol, mantleEntry.balance) : "";
|
|
8435
|
+
const heColored = heEntry ? heEntry.balance === "0.00" || heEntry.balance === "?" ? pc2.dim(heText) : heText : "";
|
|
8436
|
+
const mantleColored = mantleEntry ? mantleEntry.balance === "0.00" || mantleEntry.balance === "?" ? pc2.dim(mantleText) : mantleText : "";
|
|
8437
|
+
const visibleLen = heText.length;
|
|
8438
|
+
const padNeeded = colWidth - visibleLen;
|
|
8439
|
+
const paddedHe = heColored + (padNeeded > 0 ? " ".repeat(padNeeded) : "");
|
|
8440
|
+
console.log(paddedHe + " " + mantleColored);
|
|
8441
|
+
}
|
|
8442
|
+
console.log("");
|
|
8443
|
+
console.log(" " + pc2.bold("Commands:"));
|
|
8444
|
+
console.log(" " + pc2.cyan("defi status") + " Protocol overview");
|
|
8445
|
+
console.log(" " + pc2.cyan("defi lending rates") + " Compare lending APYs");
|
|
8446
|
+
console.log(" " + pc2.cyan("defi dex quote") + " Get swap quotes");
|
|
8447
|
+
console.log(" " + pc2.cyan("defi portfolio") + " View all positions");
|
|
8448
|
+
console.log(" " + pc2.cyan("defi scan") + " Exploit detection");
|
|
8449
|
+
console.log(" " + pc2.cyan("defi --help") + " Full command list");
|
|
8450
|
+
console.log("");
|
|
8451
|
+
}
|
|
8452
|
+
|
|
8277
8453
|
// src/main.ts
|
|
8278
8454
|
async function main() {
|
|
8279
8455
|
try {
|
|
8456
|
+
const rawArgs = process.argv.slice(2);
|
|
8457
|
+
const knownSubcommands = /* @__PURE__ */ new Set([
|
|
8458
|
+
"status",
|
|
8459
|
+
"schema",
|
|
8460
|
+
"dex",
|
|
8461
|
+
"gauge",
|
|
8462
|
+
"lending",
|
|
8463
|
+
"cdp",
|
|
8464
|
+
"staking",
|
|
8465
|
+
"vault",
|
|
8466
|
+
"yield",
|
|
8467
|
+
"portfolio",
|
|
8468
|
+
"monitor",
|
|
8469
|
+
"alert",
|
|
8470
|
+
"scan",
|
|
8471
|
+
"arb",
|
|
8472
|
+
"positions",
|
|
8473
|
+
"price",
|
|
8474
|
+
"wallet",
|
|
8475
|
+
"token",
|
|
8476
|
+
"whales",
|
|
8477
|
+
"compare",
|
|
8478
|
+
"swap",
|
|
8479
|
+
"bridge",
|
|
8480
|
+
"nft",
|
|
8481
|
+
"farm",
|
|
8482
|
+
"agent"
|
|
8483
|
+
]);
|
|
8484
|
+
const hasSubcommand = rawArgs.some((a) => !a.startsWith("-") && knownSubcommands.has(a));
|
|
8485
|
+
const isJson = rawArgs.includes("--json") || rawArgs.includes("--ndjson");
|
|
8486
|
+
const isHelp = rawArgs.includes("--help") || rawArgs.includes("-h");
|
|
8487
|
+
const isVersion = rawArgs.includes("--version") || rawArgs.includes("-V");
|
|
8488
|
+
if (!isHelp && !isVersion && (rawArgs.length === 0 || !hasSubcommand)) {
|
|
8489
|
+
await showLandingPage(isJson);
|
|
8490
|
+
return;
|
|
8491
|
+
}
|
|
8280
8492
|
await program.parseAsync(process.argv);
|
|
8281
8493
|
} catch (error) {
|
|
8282
8494
|
const isJsonMode = process.argv.includes("--json") || process.argv.includes("--ndjson");
|