@hypurrquant/defi-cli 0.1.0 → 0.2.2
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/README.md +356 -0
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/main.js +232 -21
- package/dist/main.js.map +1 -1
- package/dist/mcp-server.js +5600 -0
- package/dist/mcp-server.js.map +1 -0
- package/mcp-config.example.json +13 -0
- package/package.json +38 -6
- package/config/protocols/lending/.omc/state/last-tool-error.json +0 -7
package/dist/main.js
CHANGED
|
@@ -863,6 +863,10 @@ async function multicallRead(rpcUrl, calls) {
|
|
|
863
863
|
});
|
|
864
864
|
return decoded.map((r) => r.success ? r.returnData : null);
|
|
865
865
|
}
|
|
866
|
+
function decodeU256(data) {
|
|
867
|
+
if (!data || data.length < 66) return 0n;
|
|
868
|
+
return BigInt(data.slice(0, 66));
|
|
869
|
+
}
|
|
866
870
|
var ChainConfig = class {
|
|
867
871
|
name;
|
|
868
872
|
chain_id;
|
|
@@ -1012,9 +1016,11 @@ var DEFAULT_PRIORITY_FEE_WEI = 100000000n;
|
|
|
1012
1016
|
var Executor = class _Executor {
|
|
1013
1017
|
dryRun;
|
|
1014
1018
|
rpcUrl;
|
|
1015
|
-
|
|
1019
|
+
explorerUrl;
|
|
1020
|
+
constructor(broadcast, rpcUrl, explorerUrl) {
|
|
1016
1021
|
this.dryRun = !broadcast;
|
|
1017
1022
|
this.rpcUrl = rpcUrl;
|
|
1023
|
+
this.explorerUrl = explorerUrl;
|
|
1018
1024
|
}
|
|
1019
1025
|
/** Apply 20% buffer to a gas estimate */
|
|
1020
1026
|
static applyGasBuffer(gas) {
|
|
@@ -1149,7 +1155,10 @@ var Executor = class _Executor {
|
|
|
1149
1155
|
maxFeePerGas: maxFeePerGas > 0n ? maxFeePerGas : void 0,
|
|
1150
1156
|
maxPriorityFeePerGas: maxPriorityFeePerGas > 0n ? maxPriorityFeePerGas : void 0
|
|
1151
1157
|
});
|
|
1158
|
+
const txUrl = this.explorerUrl ? `${this.explorerUrl}/tx/${txHash}` : void 0;
|
|
1152
1159
|
process.stderr.write(`Transaction sent: ${txHash}
|
|
1160
|
+
`);
|
|
1161
|
+
if (txUrl) process.stderr.write(`Explorer: ${txUrl}
|
|
1153
1162
|
`);
|
|
1154
1163
|
process.stderr.write("Waiting for confirmation...\n");
|
|
1155
1164
|
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
@@ -1165,6 +1174,7 @@ var Executor = class _Executor {
|
|
|
1165
1174
|
block_number: receipt.blockNumber?.toString(),
|
|
1166
1175
|
gas_limit: gasLimit.toString(),
|
|
1167
1176
|
gas_used: receipt.gasUsed?.toString(),
|
|
1177
|
+
explorer_url: txUrl,
|
|
1168
1178
|
mode: "broadcast"
|
|
1169
1179
|
}
|
|
1170
1180
|
};
|
|
@@ -6114,7 +6124,7 @@ var POOL_ABI4 = parseAbi27([
|
|
|
6114
6124
|
var ORACLE_ABI5 = parseAbi27([
|
|
6115
6125
|
"function getAssetPrice(address asset) external view returns (uint256)"
|
|
6116
6126
|
]);
|
|
6117
|
-
function
|
|
6127
|
+
function decodeU2562(data, wordOffset = 0) {
|
|
6118
6128
|
if (!data || data.length < 2 + (wordOffset + 1) * 64) return 0n;
|
|
6119
6129
|
const hex = data.slice(2 + wordOffset * 64, 2 + wordOffset * 64 + 64);
|
|
6120
6130
|
return BigInt("0x" + hex);
|
|
@@ -6194,7 +6204,7 @@ function registerPortfolio(parent, getOpts) {
|
|
|
6194
6204
|
let nativePriceUsd = 0;
|
|
6195
6205
|
if (oracleAddr) {
|
|
6196
6206
|
const priceData = results[results.length - 1] ?? null;
|
|
6197
|
-
nativePriceUsd = Number(
|
|
6207
|
+
nativePriceUsd = Number(decodeU2562(priceData)) / 1e8;
|
|
6198
6208
|
}
|
|
6199
6209
|
let totalValueUsd = 0;
|
|
6200
6210
|
let idx = 0;
|
|
@@ -6208,7 +6218,7 @@ function registerPortfolio(parent, getOpts) {
|
|
|
6208
6218
|
}
|
|
6209
6219
|
if (entry.address === "0x0000000000000000000000000000000000000000") continue;
|
|
6210
6220
|
if (idx >= results.length) break;
|
|
6211
|
-
const balance =
|
|
6221
|
+
const balance = decodeU2562(results[idx] ?? null);
|
|
6212
6222
|
if (balance > 0n) {
|
|
6213
6223
|
const decimals = entry.decimals;
|
|
6214
6224
|
const balF64 = Number(balance) / 10 ** decimals;
|
|
@@ -6228,9 +6238,9 @@ function registerPortfolio(parent, getOpts) {
|
|
|
6228
6238
|
if (idx >= results.length) break;
|
|
6229
6239
|
const data = results[idx] ?? null;
|
|
6230
6240
|
if (data && data.length >= 2 + 192 * 2) {
|
|
6231
|
-
const collateral = Number(
|
|
6232
|
-
const debt = Number(
|
|
6233
|
-
const hfRaw =
|
|
6241
|
+
const collateral = Number(decodeU2562(data, 0)) / 1e8;
|
|
6242
|
+
const debt = Number(decodeU2562(data, 1)) / 1e8;
|
|
6243
|
+
const hfRaw = decodeU2562(data, 5);
|
|
6234
6244
|
let hf = null;
|
|
6235
6245
|
if (hfRaw <= BigInt("0xffffffffffffffffffffffffffffffff")) {
|
|
6236
6246
|
const v = Number(hfRaw) / 1e18;
|
|
@@ -7072,7 +7082,7 @@ function estimateTokenValue(symbol, balance, nativePrice) {
|
|
|
7072
7082
|
if (["WETH", "ETH", "METH", "CBETH", "WSTETH"].includes(s)) return balance * 2350;
|
|
7073
7083
|
return balance * nativePrice;
|
|
7074
7084
|
}
|
|
7075
|
-
function
|
|
7085
|
+
function decodeU2563(data, offset = 0) {
|
|
7076
7086
|
if (!data || data.length < 2 + (offset + 32) * 2) return 0n;
|
|
7077
7087
|
const hex = data.slice(2 + offset * 64, 2 + offset * 64 + 64);
|
|
7078
7088
|
return BigInt("0x" + hex);
|
|
@@ -7110,7 +7120,7 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
|
|
|
7110
7120
|
} catch {
|
|
7111
7121
|
return null;
|
|
7112
7122
|
}
|
|
7113
|
-
const nativePrice = oracleAddr ? Number(
|
|
7123
|
+
const nativePrice = oracleAddr ? Number(decodeU2563(results[results.length - 1])) / 1e8 : 0;
|
|
7114
7124
|
const tokenBalances = [];
|
|
7115
7125
|
const lendingPositions = [];
|
|
7116
7126
|
let chainValue = 0;
|
|
@@ -7120,7 +7130,7 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
|
|
|
7120
7130
|
const ct = callTypes[i];
|
|
7121
7131
|
const data = results[i] ?? null;
|
|
7122
7132
|
if (ct.kind === "token") {
|
|
7123
|
-
const balance =
|
|
7133
|
+
const balance = decodeU2563(data);
|
|
7124
7134
|
if (balance > 0n) {
|
|
7125
7135
|
const balF64 = Number(balance) / 10 ** ct.decimals;
|
|
7126
7136
|
const valueUsd = estimateTokenValue(ct.symbol, balF64, nativePrice);
|
|
@@ -7137,9 +7147,9 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
|
|
|
7137
7147
|
if (data && data.length >= 2 + 192 * 2) {
|
|
7138
7148
|
const priceDecimals = ct.iface === "aave_v2" ? 18 : 8;
|
|
7139
7149
|
const divisor = 10 ** priceDecimals;
|
|
7140
|
-
const collateral = Number(
|
|
7141
|
-
const debt = Number(
|
|
7142
|
-
const hfRaw =
|
|
7150
|
+
const collateral = Number(decodeU2563(data, 0)) / divisor;
|
|
7151
|
+
const debt = Number(decodeU2563(data, 1)) / divisor;
|
|
7152
|
+
const hfRaw = decodeU2563(data, 5);
|
|
7143
7153
|
let hf = null;
|
|
7144
7154
|
if (hfRaw <= BigInt("0xffffffffffffffffffffffffffffffff")) {
|
|
7145
7155
|
const v = Number(hfRaw) / 1e18;
|
|
@@ -7485,7 +7495,7 @@ function round24(x) {
|
|
|
7485
7495
|
function round43(x) {
|
|
7486
7496
|
return Math.round(x * 1e4) / 1e4;
|
|
7487
7497
|
}
|
|
7488
|
-
function
|
|
7498
|
+
function decodeU2564(data, wordOffset = 0) {
|
|
7489
7499
|
if (!data || data.length < 2 + (wordOffset + 1) * 64) return 0n;
|
|
7490
7500
|
const hex = data.slice(2 + wordOffset * 64, 2 + wordOffset * 64 + 64);
|
|
7491
7501
|
return BigInt("0x" + hex);
|
|
@@ -7610,9 +7620,9 @@ function registerWhales(parent, getOpts) {
|
|
|
7610
7620
|
if (data && data.length >= 2 + 192 * 2) {
|
|
7611
7621
|
const dec = iface === "aave_v2" ? 18 : 8;
|
|
7612
7622
|
const divisor = 10 ** dec;
|
|
7613
|
-
const collateral = Number(
|
|
7614
|
-
const debt = Number(
|
|
7615
|
-
const hfRaw =
|
|
7623
|
+
const collateral = Number(decodeU2564(data, 0)) / divisor;
|
|
7624
|
+
const debt = Number(decodeU2564(data, 1)) / divisor;
|
|
7625
|
+
const hfRaw = decodeU2564(data, 5);
|
|
7616
7626
|
let hf = null;
|
|
7617
7627
|
if (hfRaw <= BigInt("0xffffffffffffffffffffffffffffffff")) {
|
|
7618
7628
|
const v = Number(hfRaw) / 1e18;
|
|
@@ -8015,11 +8025,11 @@ function registerBridge(parent, getOpts) {
|
|
|
8015
8025
|
const amountUsdc = Number(BigInt(opts.amount)) / 1e6;
|
|
8016
8026
|
const { fee, maxFeeSubunits } = await getCctpFeeEstimate(srcDomain, dstDomain, amountUsdc);
|
|
8017
8027
|
const recipientPadded = `0x${"0".repeat(24)}${recipient.replace("0x", "").toLowerCase()}`;
|
|
8018
|
-
const { encodeFunctionData:
|
|
8019
|
-
const tokenMessengerAbi =
|
|
8028
|
+
const { encodeFunctionData: encodeFunctionData29, parseAbi: parseAbi33 } = await import("viem");
|
|
8029
|
+
const tokenMessengerAbi = parseAbi33([
|
|
8020
8030
|
"function depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller, uint256 maxFee, uint32 minFinalityThreshold) external returns (uint64 nonce)"
|
|
8021
8031
|
]);
|
|
8022
|
-
const data =
|
|
8032
|
+
const data = encodeFunctionData29({
|
|
8023
8033
|
abi: tokenMessengerAbi,
|
|
8024
8034
|
functionName: "depositForBurn",
|
|
8025
8035
|
args: [
|
|
@@ -8235,7 +8245,7 @@ function makeExecutor() {
|
|
|
8235
8245
|
const opts = program.opts();
|
|
8236
8246
|
const registry = Registry.loadEmbedded();
|
|
8237
8247
|
const chain = registry.getChain(opts.chain ?? "hyperevm");
|
|
8238
|
-
return new Executor(!!opts.broadcast, chain.effectiveRpcUrl());
|
|
8248
|
+
return new Executor(!!opts.broadcast, chain.effectiveRpcUrl(), chain.explorer_url);
|
|
8239
8249
|
}
|
|
8240
8250
|
registerStatus(program, getOutputMode);
|
|
8241
8251
|
registerSchema(program, getOutputMode);
|
|
@@ -8268,9 +8278,210 @@ program.command("agent").description("Agent mode: read JSON commands from stdin
|
|
|
8268
8278
|
process.exit(1);
|
|
8269
8279
|
});
|
|
8270
8280
|
|
|
8281
|
+
// src/landing.ts
|
|
8282
|
+
import pc2 from "picocolors";
|
|
8283
|
+
import { encodeFunctionData as encodeFunctionData28, parseAbi as parseAbi31, formatUnits } from "viem";
|
|
8284
|
+
var HYPEREVM_DISPLAY = ["HYPE", "WHYPE", "USDC", "USDT0", "USDe", "kHYPE", "wstHYPE"];
|
|
8285
|
+
var MANTLE_DISPLAY = ["MNT", "WMNT", "USDC", "USDT", "WETH", "mETH"];
|
|
8286
|
+
var balanceOfAbi = parseAbi31([
|
|
8287
|
+
"function balanceOf(address account) view returns (uint256)"
|
|
8288
|
+
]);
|
|
8289
|
+
var getEthBalanceAbi = parseAbi31([
|
|
8290
|
+
"function getEthBalance(address addr) view returns (uint256)"
|
|
8291
|
+
]);
|
|
8292
|
+
async function fetchBalances(rpcUrl, wallet, tokens) {
|
|
8293
|
+
const calls = tokens.map((t) => {
|
|
8294
|
+
const isNative = t.tags?.includes("native") || t.address === "0x0000000000000000000000000000000000000000";
|
|
8295
|
+
if (isNative) {
|
|
8296
|
+
return [
|
|
8297
|
+
MULTICALL3_ADDRESS,
|
|
8298
|
+
encodeFunctionData28({
|
|
8299
|
+
abi: getEthBalanceAbi,
|
|
8300
|
+
functionName: "getEthBalance",
|
|
8301
|
+
args: [wallet]
|
|
8302
|
+
})
|
|
8303
|
+
];
|
|
8304
|
+
}
|
|
8305
|
+
return [
|
|
8306
|
+
t.address,
|
|
8307
|
+
encodeFunctionData28({
|
|
8308
|
+
abi: balanceOfAbi,
|
|
8309
|
+
functionName: "balanceOf",
|
|
8310
|
+
args: [wallet]
|
|
8311
|
+
})
|
|
8312
|
+
];
|
|
8313
|
+
});
|
|
8314
|
+
let results;
|
|
8315
|
+
try {
|
|
8316
|
+
results = await multicallRead(rpcUrl, calls);
|
|
8317
|
+
} catch {
|
|
8318
|
+
results = tokens.map(() => null);
|
|
8319
|
+
}
|
|
8320
|
+
return tokens.map((t, i) => {
|
|
8321
|
+
const raw = decodeU256(results[i]);
|
|
8322
|
+
const formatted = formatUnits(raw, t.decimals);
|
|
8323
|
+
const num = parseFloat(formatted);
|
|
8324
|
+
const display = num === 0 ? "0.00" : num >= 1e3 ? num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 6 });
|
|
8325
|
+
return { symbol: t.symbol, balance: display, decimals: t.decimals };
|
|
8326
|
+
});
|
|
8327
|
+
}
|
|
8328
|
+
function shortenAddress(addr) {
|
|
8329
|
+
if (addr.length < 12) return addr;
|
|
8330
|
+
return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
|
|
8331
|
+
}
|
|
8332
|
+
function padRight(s, len) {
|
|
8333
|
+
return s.length >= len ? s : s + " ".repeat(len - s.length);
|
|
8334
|
+
}
|
|
8335
|
+
function padLeft(s, len) {
|
|
8336
|
+
return s.length >= len ? s : " ".repeat(len - s.length) + s;
|
|
8337
|
+
}
|
|
8338
|
+
function formatBalanceLine(sym, bal) {
|
|
8339
|
+
const symPad = padRight(sym, 10);
|
|
8340
|
+
const balPad = padLeft(bal, 12);
|
|
8341
|
+
return ` ${symPad}${balPad}`;
|
|
8342
|
+
}
|
|
8343
|
+
async function showLandingPage(isJson) {
|
|
8344
|
+
const registry = Registry.loadEmbedded();
|
|
8345
|
+
const wallet = process.env.DEFI_WALLET_ADDRESS;
|
|
8346
|
+
if (isJson) {
|
|
8347
|
+
if (!wallet) {
|
|
8348
|
+
console.log(JSON.stringify({ error: "DEFI_WALLET_ADDRESS not set" }, null, 2));
|
|
8349
|
+
return;
|
|
8350
|
+
}
|
|
8351
|
+
const heChain2 = registry.getChain("hyperevm");
|
|
8352
|
+
const mantleChain2 = registry.getChain("mantle");
|
|
8353
|
+
const heTokens2 = (registry.tokens.get("hyperevm") ?? []).filter((t) => HYPEREVM_DISPLAY.includes(t.symbol));
|
|
8354
|
+
const mantleTokens2 = (registry.tokens.get("mantle") ?? []).filter((t) => MANTLE_DISPLAY.includes(t.symbol));
|
|
8355
|
+
const heSorted2 = HYPEREVM_DISPLAY.map((s) => heTokens2.find((t) => t.symbol === s)).filter(Boolean);
|
|
8356
|
+
const mantleSorted2 = MANTLE_DISPLAY.map((s) => mantleTokens2.find((t) => t.symbol === s)).filter(Boolean);
|
|
8357
|
+
const [heBalances2, mantleBalances2] = await Promise.all([
|
|
8358
|
+
fetchBalances(heChain2.effectiveRpcUrl(), wallet, heSorted2),
|
|
8359
|
+
fetchBalances(mantleChain2.effectiveRpcUrl(), wallet, mantleSorted2)
|
|
8360
|
+
]);
|
|
8361
|
+
console.log(JSON.stringify({
|
|
8362
|
+
wallet,
|
|
8363
|
+
chains: {
|
|
8364
|
+
hyperevm: { name: heChain2.name, balances: heBalances2 },
|
|
8365
|
+
mantle: { name: mantleChain2.name, balances: mantleBalances2 }
|
|
8366
|
+
}
|
|
8367
|
+
}, null, 2));
|
|
8368
|
+
return;
|
|
8369
|
+
}
|
|
8370
|
+
const version = "0.2.0";
|
|
8371
|
+
if (!wallet) {
|
|
8372
|
+
console.log("");
|
|
8373
|
+
console.log(pc2.bold(pc2.cyan(" DeFi CLI v" + version)));
|
|
8374
|
+
console.log("");
|
|
8375
|
+
console.log(pc2.yellow(" Wallet not configured."));
|
|
8376
|
+
console.log(" Set DEFI_WALLET_ADDRESS to see your balances:");
|
|
8377
|
+
console.log("");
|
|
8378
|
+
console.log(pc2.dim(" export DEFI_WALLET_ADDRESS=0x..."));
|
|
8379
|
+
console.log("");
|
|
8380
|
+
console.log(" Commands:");
|
|
8381
|
+
console.log(pc2.dim(" defi status Protocol overview"));
|
|
8382
|
+
console.log(pc2.dim(" defi lending rates Compare lending APYs"));
|
|
8383
|
+
console.log(pc2.dim(" defi dex quote Get swap quotes"));
|
|
8384
|
+
console.log(pc2.dim(" defi portfolio View all positions"));
|
|
8385
|
+
console.log(pc2.dim(" defi scan Exploit detection"));
|
|
8386
|
+
console.log(pc2.dim(" defi --help Full command list"));
|
|
8387
|
+
console.log("");
|
|
8388
|
+
return;
|
|
8389
|
+
}
|
|
8390
|
+
const heChain = registry.getChain("hyperevm");
|
|
8391
|
+
const mantleChain = registry.getChain("mantle");
|
|
8392
|
+
const heTokens = (registry.tokens.get("hyperevm") ?? []).filter((t) => HYPEREVM_DISPLAY.includes(t.symbol));
|
|
8393
|
+
const mantleTokens = (registry.tokens.get("mantle") ?? []).filter((t) => MANTLE_DISPLAY.includes(t.symbol));
|
|
8394
|
+
const heSorted = HYPEREVM_DISPLAY.map((s) => heTokens.find((t) => t.symbol === s)).filter(Boolean);
|
|
8395
|
+
const mantleSorted = MANTLE_DISPLAY.map((s) => mantleTokens.find((t) => t.symbol === s)).filter(Boolean);
|
|
8396
|
+
const [heBalances, mantleBalances] = await Promise.all([
|
|
8397
|
+
fetchBalances(heChain.effectiveRpcUrl(), wallet, heSorted).catch(
|
|
8398
|
+
() => heSorted.map((t) => ({ symbol: t.symbol, balance: "?", decimals: t.decimals }))
|
|
8399
|
+
),
|
|
8400
|
+
fetchBalances(mantleChain.effectiveRpcUrl(), wallet, mantleSorted).catch(
|
|
8401
|
+
() => mantleSorted.map((t) => ({ symbol: t.symbol, balance: "?", decimals: t.decimals }))
|
|
8402
|
+
)
|
|
8403
|
+
]);
|
|
8404
|
+
const colWidth = 38;
|
|
8405
|
+
const divider = "\u2500".repeat(colWidth - 2);
|
|
8406
|
+
console.log("");
|
|
8407
|
+
console.log(
|
|
8408
|
+
pc2.bold(pc2.cyan(" DeFi CLI v" + version)) + pc2.dim(" \u2014 ") + pc2.bold(heChain.name) + pc2.dim(" \xB7 ") + pc2.bold(mantleChain.name)
|
|
8409
|
+
);
|
|
8410
|
+
console.log("");
|
|
8411
|
+
console.log(" Wallet: " + pc2.yellow(shortenAddress(wallet)));
|
|
8412
|
+
console.log("");
|
|
8413
|
+
const heHeader = padRight(
|
|
8414
|
+
" " + pc2.bold(heChain.name),
|
|
8415
|
+
colWidth + 10
|
|
8416
|
+
/* account for ANSI */
|
|
8417
|
+
);
|
|
8418
|
+
const mantleHeader = pc2.bold(mantleChain.name);
|
|
8419
|
+
console.log(heHeader + " " + mantleHeader);
|
|
8420
|
+
const heDivider = padRight(" " + pc2.dim(divider), colWidth + 10);
|
|
8421
|
+
const mantleDivider = pc2.dim(divider);
|
|
8422
|
+
console.log(heDivider + " " + mantleDivider);
|
|
8423
|
+
const maxRows = Math.max(heBalances.length, mantleBalances.length);
|
|
8424
|
+
for (let i = 0; i < maxRows; i++) {
|
|
8425
|
+
const heEntry = heBalances[i];
|
|
8426
|
+
const mantleEntry = mantleBalances[i];
|
|
8427
|
+
const heText = heEntry ? formatBalanceLine(heEntry.symbol, heEntry.balance) : "";
|
|
8428
|
+
const mantleText = mantleEntry ? formatBalanceLine(mantleEntry.symbol, mantleEntry.balance) : "";
|
|
8429
|
+
const heColored = heEntry ? heEntry.balance === "0.00" || heEntry.balance === "?" ? pc2.dim(heText) : heText : "";
|
|
8430
|
+
const mantleColored = mantleEntry ? mantleEntry.balance === "0.00" || mantleEntry.balance === "?" ? pc2.dim(mantleText) : mantleText : "";
|
|
8431
|
+
const visibleLen = heText.length;
|
|
8432
|
+
const padNeeded = colWidth - visibleLen;
|
|
8433
|
+
const paddedHe = heColored + (padNeeded > 0 ? " ".repeat(padNeeded) : "");
|
|
8434
|
+
console.log(paddedHe + " " + mantleColored);
|
|
8435
|
+
}
|
|
8436
|
+
console.log("");
|
|
8437
|
+
console.log(" " + pc2.bold("Commands:"));
|
|
8438
|
+
console.log(" " + pc2.cyan("defi status") + " Protocol overview");
|
|
8439
|
+
console.log(" " + pc2.cyan("defi lending rates") + " Compare lending APYs");
|
|
8440
|
+
console.log(" " + pc2.cyan("defi dex quote") + " Get swap quotes");
|
|
8441
|
+
console.log(" " + pc2.cyan("defi portfolio") + " View all positions");
|
|
8442
|
+
console.log(" " + pc2.cyan("defi scan") + " Exploit detection");
|
|
8443
|
+
console.log(" " + pc2.cyan("defi --help") + " Full command list");
|
|
8444
|
+
console.log("");
|
|
8445
|
+
}
|
|
8446
|
+
|
|
8271
8447
|
// src/main.ts
|
|
8272
8448
|
async function main() {
|
|
8273
8449
|
try {
|
|
8450
|
+
const rawArgs = process.argv.slice(2);
|
|
8451
|
+
const knownSubcommands = /* @__PURE__ */ new Set([
|
|
8452
|
+
"status",
|
|
8453
|
+
"schema",
|
|
8454
|
+
"dex",
|
|
8455
|
+
"gauge",
|
|
8456
|
+
"lending",
|
|
8457
|
+
"cdp",
|
|
8458
|
+
"staking",
|
|
8459
|
+
"vault",
|
|
8460
|
+
"yield",
|
|
8461
|
+
"portfolio",
|
|
8462
|
+
"monitor",
|
|
8463
|
+
"alert",
|
|
8464
|
+
"scan",
|
|
8465
|
+
"arb",
|
|
8466
|
+
"positions",
|
|
8467
|
+
"price",
|
|
8468
|
+
"wallet",
|
|
8469
|
+
"token",
|
|
8470
|
+
"whales",
|
|
8471
|
+
"compare",
|
|
8472
|
+
"swap",
|
|
8473
|
+
"bridge",
|
|
8474
|
+
"nft",
|
|
8475
|
+
"farm",
|
|
8476
|
+
"agent"
|
|
8477
|
+
]);
|
|
8478
|
+
const hasSubcommand = rawArgs.some((a) => !a.startsWith("-") && knownSubcommands.has(a));
|
|
8479
|
+
const isJson = rawArgs.includes("--json") || rawArgs.includes("--ndjson");
|
|
8480
|
+
const isHelp = rawArgs.includes("--help") || rawArgs.includes("-h");
|
|
8481
|
+
if (!isHelp && (rawArgs.length === 0 || !hasSubcommand)) {
|
|
8482
|
+
await showLandingPage(isJson);
|
|
8483
|
+
return;
|
|
8484
|
+
}
|
|
8274
8485
|
await program.parseAsync(process.argv);
|
|
8275
8486
|
} catch (error) {
|
|
8276
8487
|
const isJsonMode = process.argv.includes("--json") || process.argv.includes("--ndjson");
|