@hypurrquant/defi-cli 0.3.4 → 0.3.5

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/main.js CHANGED
@@ -6966,7 +6966,11 @@ function registerLP(parent, getOpts, makeExecutor2) {
6966
6966
  pair: `${p.symbolX}/${p.symbolY}`,
6967
6967
  type: "EMISSION",
6968
6968
  source: "lb_hooks",
6969
- stopped: p.stopped
6969
+ stopped: p.stopped,
6970
+ moePerDay: p.moePerDay,
6971
+ aprPercent: p.aprPercent,
6972
+ rangeTvlUsd: p.rangeTvlUsd,
6973
+ isTopPool: p.isTopPool
6970
6974
  });
6971
6975
  }
6972
6976
  }
@@ -9968,6 +9972,209 @@ function registerBridge(parent, getOpts) {
9968
9972
  });
9969
9973
  }
9970
9974
 
9975
+ // src/commands/swap.ts
9976
+ var CHAIN_NAMES = {
9977
+ hyperevm: { kyber: "hyperevm", openocean: "hyperevm" },
9978
+ mantle: { openocean: "mantle" }
9979
+ };
9980
+ var KYBER_API = "https://aggregator-api.kyberswap.com";
9981
+ async function kyberGetQuote(chain, tokenIn, tokenOut, amountIn) {
9982
+ const params = new URLSearchParams({ tokenIn, tokenOut, amountIn });
9983
+ const url = `${KYBER_API}/${chain}/api/v1/routes?${params}`;
9984
+ const res = await fetch(url, { headers: { "x-client-id": "defi-cli" } });
9985
+ if (!res.ok) throw new Error(`KyberSwap quote failed: ${res.status} ${await res.text()}`);
9986
+ const json = await res.json();
9987
+ const data = json.data;
9988
+ if (!data?.routeSummary) throw new Error(`KyberSwap: no route found`);
9989
+ return data;
9990
+ }
9991
+ async function kyberBuildTx(chain, routeSummary, sender, recipient, slippageTolerance) {
9992
+ const url = `${KYBER_API}/${chain}/api/v1/route/build`;
9993
+ const res = await fetch(url, {
9994
+ method: "POST",
9995
+ headers: { "Content-Type": "application/json", "x-client-id": "defi-cli" },
9996
+ body: JSON.stringify({ routeSummary, sender, recipient, slippageTolerance })
9997
+ });
9998
+ if (!res.ok) throw new Error(`KyberSwap build failed: ${res.status} ${await res.text()}`);
9999
+ const json = await res.json();
10000
+ const data = json.data;
10001
+ if (!data) throw new Error("KyberSwap: no build data");
10002
+ return {
10003
+ to: String(data.routerAddress),
10004
+ data: String(data.data),
10005
+ value: String(data.value ?? "0x0")
10006
+ };
10007
+ }
10008
+ var OPENOCEAN_API = "https://open-api.openocean.finance/v4";
10009
+ async function openoceanSwap(chain, inTokenAddress, outTokenAddress, amountIn, slippagePct, account) {
10010
+ const params = new URLSearchParams({
10011
+ inTokenAddress,
10012
+ outTokenAddress,
10013
+ amount: amountIn,
10014
+ gasPrice: "0.1",
10015
+ slippage: slippagePct,
10016
+ account
10017
+ });
10018
+ const url = `${OPENOCEAN_API}/${chain}/swap?${params}`;
10019
+ const res = await fetch(url);
10020
+ if (!res.ok) throw new Error(`OpenOcean swap failed: ${res.status} ${await res.text()}`);
10021
+ const json = await res.json();
10022
+ const data = json.data;
10023
+ if (!data) throw new Error("OpenOcean: no swap data");
10024
+ return {
10025
+ to: String(data.to),
10026
+ data: String(data.data),
10027
+ value: String(data.value ?? "0x0"),
10028
+ outAmount: String(data.outAmount ?? "0")
10029
+ };
10030
+ }
10031
+ var LIQD_API = "https://api.liqd.ag/v2";
10032
+ var LIQD_ROUTER = "0x744489ee3d540777a66f2cf297479745e0852f7a";
10033
+ async function liquidSwapRoute(tokenIn, tokenOut, amountIn, slippagePct) {
10034
+ const params = new URLSearchParams({ tokenIn, tokenOut, amountIn, slippage: slippagePct });
10035
+ const url = `${LIQD_API}/route?${params}`;
10036
+ const res = await fetch(url);
10037
+ if (!res.ok) throw new Error(`LiquidSwap route failed: ${res.status} ${await res.text()}`);
10038
+ const json = await res.json();
10039
+ const execution = json.execution;
10040
+ if (!execution) throw new Error("LiquidSwap: no execution data in response");
10041
+ const details = json.details;
10042
+ return {
10043
+ to: String(execution.to ?? LIQD_ROUTER),
10044
+ data: String(execution.calldata),
10045
+ value: String(execution.value ?? "0x0"),
10046
+ outAmount: String(details?.amountOut ?? json.amountOut ?? "0")
10047
+ };
10048
+ }
10049
+ function registerSwap(parent, getOpts, makeExecutor2) {
10050
+ parent.command("swap").description("Swap tokens via DEX aggregator (KyberSwap, OpenOcean, LiquidSwap)").requiredOption("--from <token>", "Input token symbol or address").requiredOption("--to <token>", "Output token symbol or address").requiredOption("--amount <amount>", "Amount of input token in wei").option("--provider <name>", "Aggregator: kyber, openocean, liquid", "kyber").option("--slippage <bps>", "Slippage tolerance in bps", "50").action(async (opts) => {
10051
+ const executor = makeExecutor2();
10052
+ const chainName = parent.opts().chain ?? "hyperevm";
10053
+ const registry = Registry.loadEmbedded();
10054
+ const provider = opts.provider.toLowerCase();
10055
+ const slippageBps = parseInt(opts.slippage, 10);
10056
+ const fromAddr = opts.from.startsWith("0x") ? opts.from : registry.resolveToken(chainName, opts.from).address;
10057
+ const toAddr = opts.to.startsWith("0x") ? opts.to : registry.resolveToken(chainName, opts.to).address;
10058
+ const wallet = process.env["DEFI_WALLET_ADDRESS"] ?? "0x0000000000000000000000000000000000000001";
10059
+ if (provider === "kyber") {
10060
+ const chainNames = CHAIN_NAMES[chainName];
10061
+ if (!chainNames?.kyber) {
10062
+ printOutput({ error: `KyberSwap: unsupported chain '${chainName}'. Supported: hyperevm` }, getOpts());
10063
+ return;
10064
+ }
10065
+ const kyberChain = chainNames.kyber;
10066
+ try {
10067
+ const quoteData = await kyberGetQuote(kyberChain, fromAddr, toAddr, opts.amount);
10068
+ const routeSummary = quoteData.routeSummary;
10069
+ const amountOut = String(routeSummary.amountOut ?? "0");
10070
+ const txData = await kyberBuildTx(
10071
+ kyberChain,
10072
+ routeSummary,
10073
+ wallet,
10074
+ wallet,
10075
+ slippageBps
10076
+ );
10077
+ const tx = {
10078
+ description: `KyberSwap: swap ${opts.amount} of ${fromAddr} -> ${toAddr}`,
10079
+ to: txData.to,
10080
+ data: txData.data,
10081
+ value: txData.value.startsWith("0x") ? BigInt(txData.value) : BigInt(txData.value || 0),
10082
+ approvals: [{ token: fromAddr, spender: txData.to, amount: BigInt(opts.amount) }]
10083
+ };
10084
+ const result = await executor.execute(tx);
10085
+ printOutput({
10086
+ provider: "kyber",
10087
+ chain: kyberChain,
10088
+ from_token: fromAddr,
10089
+ to_token: toAddr,
10090
+ amount_in: opts.amount,
10091
+ amount_out: amountOut,
10092
+ router: txData.to,
10093
+ ...result
10094
+ }, getOpts());
10095
+ } catch (e) {
10096
+ printOutput({ error: `KyberSwap error: ${e instanceof Error ? e.message : String(e)}` }, getOpts());
10097
+ }
10098
+ return;
10099
+ }
10100
+ if (provider === "openocean") {
10101
+ const chainNames = CHAIN_NAMES[chainName];
10102
+ if (!chainNames) {
10103
+ printOutput({ error: `OpenOcean: unsupported chain '${chainName}'. Supported: ${Object.keys(CHAIN_NAMES).join(", ")}` }, getOpts());
10104
+ return;
10105
+ }
10106
+ const ooChain = chainNames.openocean;
10107
+ const fromToken = opts.from.startsWith("0x") ? registry.tokens.get(chainName)?.find((t) => t.address.toLowerCase() === opts.from.toLowerCase()) : registry.tokens.get(chainName)?.find((t) => t.symbol.toLowerCase() === opts.from.toLowerCase());
10108
+ const fromDecimals = fromToken?.decimals ?? 18;
10109
+ const humanAmount = (Number(opts.amount) / 10 ** fromDecimals).toString();
10110
+ const slippagePct = (slippageBps / 100).toFixed(2);
10111
+ try {
10112
+ const swap = await openoceanSwap(
10113
+ ooChain,
10114
+ fromAddr,
10115
+ toAddr,
10116
+ humanAmount,
10117
+ slippagePct,
10118
+ wallet
10119
+ );
10120
+ const tx = {
10121
+ description: `OpenOcean: swap ${opts.amount} of ${fromAddr} -> ${toAddr}`,
10122
+ to: swap.to,
10123
+ data: swap.data,
10124
+ value: swap.value.startsWith("0x") ? BigInt(swap.value) : BigInt(swap.value || 0),
10125
+ approvals: [{ token: fromAddr, spender: swap.to, amount: BigInt(opts.amount) }]
10126
+ };
10127
+ const result = await executor.execute(tx);
10128
+ printOutput({
10129
+ provider: "openocean",
10130
+ chain: ooChain,
10131
+ from_token: fromAddr,
10132
+ to_token: toAddr,
10133
+ amount_in: opts.amount,
10134
+ amount_out: swap.outAmount,
10135
+ router: swap.to,
10136
+ ...result
10137
+ }, getOpts());
10138
+ } catch (e) {
10139
+ printOutput({ error: `OpenOcean error: ${e instanceof Error ? e.message : String(e)}` }, getOpts());
10140
+ }
10141
+ return;
10142
+ }
10143
+ if (provider === "liquid") {
10144
+ if (chainName !== "hyperevm") {
10145
+ printOutput({ error: `LiquidSwap only supports hyperevm, got '${chainName}'` }, getOpts());
10146
+ return;
10147
+ }
10148
+ const slippagePct = (slippageBps / 100).toFixed(2);
10149
+ try {
10150
+ const route = await liquidSwapRoute(fromAddr, toAddr, opts.amount, slippagePct);
10151
+ const tx = {
10152
+ description: `LiquidSwap: swap ${opts.amount} of ${fromAddr} -> ${toAddr}`,
10153
+ to: route.to,
10154
+ data: route.data,
10155
+ value: route.value.startsWith("0x") ? BigInt(route.value) : BigInt(route.value || 0),
10156
+ approvals: [{ token: fromAddr, spender: route.to, amount: BigInt(opts.amount) }]
10157
+ };
10158
+ const result = await executor.execute(tx);
10159
+ printOutput({
10160
+ provider: "liquid",
10161
+ chain: chainName,
10162
+ from_token: fromAddr,
10163
+ to_token: toAddr,
10164
+ amount_in: opts.amount,
10165
+ amount_out: route.outAmount,
10166
+ router: route.to,
10167
+ ...result
10168
+ }, getOpts());
10169
+ } catch (e) {
10170
+ printOutput({ error: `LiquidSwap error: ${e instanceof Error ? e.message : String(e)}` }, getOpts());
10171
+ }
10172
+ return;
10173
+ }
10174
+ printOutput({ error: `Unknown provider '${opts.provider}'. Choose: kyber, openocean, liquid` }, getOpts());
10175
+ });
10176
+ }
10177
+
9971
10178
  // src/commands/setup.ts
9972
10179
  import pc2 from "picocolors";
9973
10180
  import { createInterface } from "readline";
@@ -10156,6 +10363,7 @@ registerWallet(program, getOutputMode);
10156
10363
  registerToken(program, getOutputMode, makeExecutor);
10157
10364
  registerWhales(program, getOutputMode);
10158
10365
  registerBridge(program, getOutputMode);
10366
+ registerSwap(program, getOutputMode, makeExecutor);
10159
10367
  registerSetup(program);
10160
10368
 
10161
10369
  // src/landing.ts
@@ -10263,7 +10471,7 @@ async function showLandingPage(isJson) {
10263
10471
  console.log(" Commands:");
10264
10472
  console.log(pc3.dim(" defi status Protocol overview"));
10265
10473
  console.log(pc3.dim(" defi lending rates Compare lending APYs"));
10266
- console.log(pc3.dim(" defi dex quote Get swap quotes"));
10474
+ console.log(pc3.dim(" defi lp discover Find LP farming pools"));
10267
10475
  console.log(pc3.dim(" defi portfolio View all positions"));
10268
10476
  console.log(pc3.dim(" defi scan Exploit detection"));
10269
10477
  console.log(pc3.dim(" defi --help Full command list"));
@@ -10351,6 +10559,7 @@ async function main() {
10351
10559
  "token",
10352
10560
  "whales",
10353
10561
  "bridge",
10562
+ "swap",
10354
10563
  "agent",
10355
10564
  "setup",
10356
10565
  "init"