@byreal-io/byreal-cli-realclaw 0.3.9 → 0.3.10
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 +1 -0
- package/dist/index.cjs +136 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,6 +85,7 @@ All commands support `-o json` for structured output.
|
|
|
85
85
|
| `wallet balance` | Query wallet balance |
|
|
86
86
|
| `jup swap` | Swap tokens via Jupiter aggregator |
|
|
87
87
|
| `jup price` | Get token price from Jupiter |
|
|
88
|
+
| `kamino reserves` | Show Kamino Lend APY for SOL/USDC/USDT (or a specific token) |
|
|
88
89
|
| `kamino deposit` | Deposit tokens into Kamino Lend |
|
|
89
90
|
| `kamino withdraw` | Withdraw tokens from Kamino Lend |
|
|
90
91
|
| `kamino status` | View Kamino lending positions and yield |
|
package/dist/index.cjs
CHANGED
|
@@ -3033,7 +3033,7 @@ var INJECTED_VERSION, VERSION, CLI_NAME, NPM_PACKAGE, API_BASE_URL, API_ENDPOINT
|
|
|
3033
3033
|
var init_constants = __esm({
|
|
3034
3034
|
"src/core/constants.ts"() {
|
|
3035
3035
|
"use strict";
|
|
3036
|
-
INJECTED_VERSION = true ? "0.3.
|
|
3036
|
+
INJECTED_VERSION = true ? "0.3.10" : void 0;
|
|
3037
3037
|
VERSION = INJECTED_VERSION ?? process.env.npm_package_version ?? "0.0.0";
|
|
3038
3038
|
CLI_NAME = "byreal-cli";
|
|
3039
3039
|
NPM_PACKAGE = "@byreal-io/byreal-cli-realclaw";
|
|
@@ -84350,6 +84350,7 @@ byreal-cli catalog show dex.pool.list
|
|
|
84350
84350
|
| update.install | Install latest CLI version |
|
|
84351
84351
|
| defi.jup.swap | Swap tokens via Jupiter aggregator |
|
|
84352
84352
|
| defi.jup.price | Get token prices from Jupiter |
|
|
84353
|
+
| defi.kamino.reserves | Show Kamino Lend APY for SOL/USDC/USDT (or a specific --token) |
|
|
84353
84354
|
| defi.kamino.deposit | Deposit to Kamino Lend |
|
|
84354
84355
|
| defi.kamino.withdraw | Withdraw from Kamino Lend |
|
|
84355
84356
|
| defi.kamino.status | View Kamino positions and APY |
|
|
@@ -84424,6 +84425,8 @@ Present on-chain data first, then external context, then synthesize how external
|
|
|
84424
84425
|
| Jupiter swap preview | \`byreal-cli jup swap --input-mint <mint> --output-mint <mint> --amount <amt> --dry-run --wallet-address <addr>\` |
|
|
84425
84426
|
| Jupiter swap execute | \`byreal-cli jup swap --input-mint <mint> --output-mint <mint> --amount <amt> --wallet-address <addr>\` |
|
|
84426
84427
|
| Jupiter token price | \`byreal-cli jup price --mint <mint>\` |
|
|
84428
|
+
| Kamino APY (SOL/USDC/USDT) | \`byreal-cli kamino reserves\` |
|
|
84429
|
+
| Kamino APY (specific token) | \`byreal-cli kamino reserves --token <symbol|mint>\` |
|
|
84427
84430
|
| Kamino deposit | \`byreal-cli kamino deposit --amount <amt> --wallet-address <addr>\` |
|
|
84428
84431
|
| Kamino withdraw | \`byreal-cli kamino withdraw --amount <amt> --wallet-address <addr>\` |
|
|
84429
84432
|
| Kamino status | \`byreal-cli kamino status --wallet-address <addr>\` |
|
|
@@ -84556,9 +84559,10 @@ When user wants to swap tokens via Jupiter (not the built-in Byreal swap):
|
|
|
84556
84559
|
## Workflow: Idle Yield with Kamino
|
|
84557
84560
|
|
|
84558
84561
|
When user wants to earn yield on idle tokens (e.g. USDC):
|
|
84559
|
-
1. **Check
|
|
84560
|
-
2. **
|
|
84561
|
-
3. **
|
|
84562
|
+
1. **Check APY**: \`byreal-cli kamino reserves\` \u2014 shows the supply/borrow APY for SOL, USDC, USDT. For any other token, pass \`--token <symbol|mint>\` (e.g. \`--token JitoSOL\`). This is an aid, not a browser \u2014 do not attempt to list every reserve.
|
|
84563
|
+
2. **Check status**: \`byreal-cli kamino status --wallet-address <addr>\` \u2014 view current positions and APY
|
|
84564
|
+
3. **Deposit**: \`byreal-cli kamino deposit --amount <amt> --wallet-address <addr>\` \u2014 deposit USDC (default) or specify \`--mint <mint>\` for other tokens
|
|
84565
|
+
4. **Withdraw**: \`byreal-cli kamino withdraw --amount <amt> --wallet-address <addr>\` \u2014 withdraw back to wallet
|
|
84562
84566
|
|
|
84563
84567
|
Default market: Kamino Main Market. Use \`--market <address>\` for a different market.
|
|
84564
84568
|
|
|
@@ -84999,23 +85003,43 @@ function sfToRaw(valueSf) {
|
|
|
84999
85003
|
return "0";
|
|
85000
85004
|
}
|
|
85001
85005
|
}
|
|
85002
|
-
|
|
85006
|
+
function toReserveMetrics(r) {
|
|
85007
|
+
const totalSupplyUsd = parseFloat(r.totalSupplyUsd) || 0;
|
|
85008
|
+
const totalBorrowUsd = parseFloat(r.totalBorrowUsd) || 0;
|
|
85009
|
+
return {
|
|
85010
|
+
reserveAddress: r.reserve,
|
|
85011
|
+
mintAddress: r.liquidityTokenMint,
|
|
85012
|
+
symbol: r.liquidityToken,
|
|
85013
|
+
supplyApy: parseFloat(r.supplyApy) || 0,
|
|
85014
|
+
borrowApy: parseFloat(r.borrowApy) || 0,
|
|
85015
|
+
totalSupplyUsd,
|
|
85016
|
+
totalBorrowUsd,
|
|
85017
|
+
utilization: totalSupplyUsd > 0 ? totalBorrowUsd / totalSupplyUsd : 0,
|
|
85018
|
+
maxLtv: parseFloat(r.maxLtv) || 0
|
|
85019
|
+
};
|
|
85020
|
+
}
|
|
85021
|
+
async function getReservesMetrics(market) {
|
|
85003
85022
|
try {
|
|
85004
85023
|
const response = await fetch(`${KAMINO_API}/kamino-market/${market}/reserves/metrics`);
|
|
85005
|
-
if (!response.ok)
|
|
85006
|
-
|
|
85007
|
-
|
|
85008
|
-
for (const r of data) {
|
|
85009
|
-
result[r.reserve] = {
|
|
85010
|
-
supplyApy: parseFloat(r.supplyApy) || 0,
|
|
85011
|
-
borrowApy: parseFloat(r.borrowApy) || 0
|
|
85012
|
-
};
|
|
85024
|
+
if (!response.ok) {
|
|
85025
|
+
const text = await response.text();
|
|
85026
|
+
return err(apiError(`Kamino reserves metrics failed: ${text}`, response.status));
|
|
85013
85027
|
}
|
|
85014
|
-
|
|
85015
|
-
|
|
85016
|
-
|
|
85028
|
+
const data = await response.json();
|
|
85029
|
+
return ok(data.map(toReserveMetrics));
|
|
85030
|
+
} catch (error) {
|
|
85031
|
+
return err(networkError(`Kamino reserves metrics: ${error.message}`));
|
|
85017
85032
|
}
|
|
85018
85033
|
}
|
|
85034
|
+
async function getReserveApyMap(market) {
|
|
85035
|
+
const result = await getReservesMetrics(market);
|
|
85036
|
+
if (!result.ok) return {};
|
|
85037
|
+
const map = {};
|
|
85038
|
+
for (const r of result.value) {
|
|
85039
|
+
map[r.reserveAddress] = { supplyApy: r.supplyApy, borrowApy: r.borrowApy };
|
|
85040
|
+
}
|
|
85041
|
+
return map;
|
|
85042
|
+
}
|
|
85019
85043
|
async function getExchangeRate(market, reserve) {
|
|
85020
85044
|
try {
|
|
85021
85045
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -85054,7 +85078,7 @@ async function enrichObligations(rawObligations, market) {
|
|
|
85054
85078
|
}
|
|
85055
85079
|
const [priceResult, reserveMetrics, ...exchangeRateResults] = await Promise.all([
|
|
85056
85080
|
mintsToPrice.size > 0 ? getPrice([...mintsToPrice]) : Promise.resolve({ ok: false, error: null }),
|
|
85057
|
-
|
|
85081
|
+
getReserveApyMap(market),
|
|
85058
85082
|
...[...activeReserves].map((r) => getExchangeRate(market, r).then((rate) => ({ reserve: r, rate })))
|
|
85059
85083
|
]);
|
|
85060
85084
|
const prices = priceResult.ok ? priceResult.value : {};
|
|
@@ -85265,6 +85289,88 @@ Error: ${message}`));
|
|
|
85265
85289
|
}
|
|
85266
85290
|
});
|
|
85267
85291
|
}
|
|
85292
|
+
var DEFAULT_RESERVE_SYMBOLS = ["SOL", "USDC", "USDT"];
|
|
85293
|
+
function formatUsdThousands(value) {
|
|
85294
|
+
return `$${value.toLocaleString("en-US", { maximumFractionDigits: 2 })}`;
|
|
85295
|
+
}
|
|
85296
|
+
function createKaminoReservesCommand() {
|
|
85297
|
+
return new Command("reserves").description("Show Kamino Lend supply/borrow APY for SOL, USDC, USDT (or a specific --token)").option("--market <address>", "Market address", KAMINO_MAIN_MARKET).option("--token <symbolOrMint>", "Query a single token by symbol (e.g. JitoSOL) or mint address instead of the default set").action(async (options, cmdObj) => {
|
|
85298
|
+
const globalOptions = cmdObj.optsWithGlobals();
|
|
85299
|
+
const format = globalOptions.output;
|
|
85300
|
+
const startTime = Date.now();
|
|
85301
|
+
try {
|
|
85302
|
+
const result = await getReservesMetrics(options.market);
|
|
85303
|
+
if (!result.ok) {
|
|
85304
|
+
format === "json" ? outputErrorJson(result.error) : outputErrorTable(result.error);
|
|
85305
|
+
process.exit(1);
|
|
85306
|
+
}
|
|
85307
|
+
const all = result.value;
|
|
85308
|
+
let reserves;
|
|
85309
|
+
if (options.token) {
|
|
85310
|
+
const needle = String(options.token).trim();
|
|
85311
|
+
const bySymbol = all.filter((r) => r.symbol.toLowerCase() === needle.toLowerCase());
|
|
85312
|
+
const byMint = all.filter((r) => r.mintAddress === needle);
|
|
85313
|
+
reserves = bySymbol.length > 0 ? bySymbol : byMint;
|
|
85314
|
+
if (reserves.length === 0) {
|
|
85315
|
+
const msg = `Token "${needle}" not found in Kamino market ${options.market}. Pass a valid symbol (e.g. JitoSOL) or mint address.`;
|
|
85316
|
+
format === "json" ? outputErrorJson({ code: "NOT_FOUND", type: "VALIDATION", message: msg, retryable: false }) : console.error(source_default.red(`
|
|
85317
|
+
Error: ${msg}`));
|
|
85318
|
+
process.exit(1);
|
|
85319
|
+
}
|
|
85320
|
+
} else {
|
|
85321
|
+
const order = new Map(DEFAULT_RESERVE_SYMBOLS.map((s, i) => [s, i]));
|
|
85322
|
+
reserves = all.filter((r) => order.has(r.symbol)).sort((a, b) => (order.get(a.symbol) ?? 0) - (order.get(b.symbol) ?? 0));
|
|
85323
|
+
}
|
|
85324
|
+
if (format === "json") {
|
|
85325
|
+
outputJson({
|
|
85326
|
+
market: options.market,
|
|
85327
|
+
query: options.token ?? "default",
|
|
85328
|
+
total: reserves.length,
|
|
85329
|
+
reserves
|
|
85330
|
+
}, startTime);
|
|
85331
|
+
return;
|
|
85332
|
+
}
|
|
85333
|
+
const table = new import_cli_table33.default({
|
|
85334
|
+
head: [
|
|
85335
|
+
source_default.cyan.bold("Token"),
|
|
85336
|
+
source_default.cyan.bold("Supply APY"),
|
|
85337
|
+
source_default.cyan.bold("Borrow APY"),
|
|
85338
|
+
source_default.cyan.bold("TVL (USD)"),
|
|
85339
|
+
source_default.cyan.bold("Borrowed (USD)"),
|
|
85340
|
+
source_default.cyan.bold("Utilization"),
|
|
85341
|
+
source_default.cyan.bold("Max LTV"),
|
|
85342
|
+
source_default.cyan.bold("Mint"),
|
|
85343
|
+
source_default.cyan.bold("Reserve")
|
|
85344
|
+
],
|
|
85345
|
+
chars: TABLE_CHARS
|
|
85346
|
+
});
|
|
85347
|
+
for (const r of reserves) {
|
|
85348
|
+
table.push([
|
|
85349
|
+
r.symbol,
|
|
85350
|
+
`${(r.supplyApy * 100).toFixed(2)}%`,
|
|
85351
|
+
`${(r.borrowApy * 100).toFixed(2)}%`,
|
|
85352
|
+
formatUsdThousands(r.totalSupplyUsd),
|
|
85353
|
+
formatUsdThousands(r.totalBorrowUsd),
|
|
85354
|
+
`${(r.utilization * 100).toFixed(2)}%`,
|
|
85355
|
+
`${(r.maxLtv * 100).toFixed(0)}%`,
|
|
85356
|
+
r.mintAddress,
|
|
85357
|
+
r.reserveAddress
|
|
85358
|
+
]);
|
|
85359
|
+
}
|
|
85360
|
+
console.log(source_default.cyan.bold("\n Kamino Lend Reserves"));
|
|
85361
|
+
console.log(source_default.gray(` Market: ${options.market}`));
|
|
85362
|
+
if (!options.token) {
|
|
85363
|
+
console.log(source_default.gray(` Showing default set: ${DEFAULT_RESERVE_SYMBOLS.join(", ")} (use --token <symbol|mint> for others)`));
|
|
85364
|
+
}
|
|
85365
|
+
console.log(table.toString());
|
|
85366
|
+
} catch (e) {
|
|
85367
|
+
const message = e.message || "Kamino reserves failed";
|
|
85368
|
+
format === "json" ? outputErrorJson({ code: "API_ERROR", type: "NETWORK", message, retryable: true }) : console.error(source_default.red(`
|
|
85369
|
+
Error: ${message}`));
|
|
85370
|
+
process.exit(1);
|
|
85371
|
+
}
|
|
85372
|
+
});
|
|
85373
|
+
}
|
|
85268
85374
|
function createKaminoStatusCommand() {
|
|
85269
85375
|
return new Command("status").description("View Kamino Lend positions and APY").option("--market <address>", "Market address", KAMINO_MAIN_MARKET).action(async (options, cmdObj) => {
|
|
85270
85376
|
const globalOptions = cmdObj.optsWithGlobals();
|
|
@@ -85367,6 +85473,18 @@ var capabilities2 = [
|
|
|
85367
85473
|
params: [
|
|
85368
85474
|
{ name: "market", type: "string", required: false, description: "Kamino market address", default: "main market" }
|
|
85369
85475
|
]
|
|
85476
|
+
},
|
|
85477
|
+
{
|
|
85478
|
+
id: "defi.kamino.reserves",
|
|
85479
|
+
name: "Kamino Reserves",
|
|
85480
|
+
description: "Show Kamino Lend supply/borrow APY for SOL, USDC, USDT by default. Use --token <symbol|mint> to query a specific other token.",
|
|
85481
|
+
category: "query",
|
|
85482
|
+
auth_required: false,
|
|
85483
|
+
command: "byreal-cli kamino reserves",
|
|
85484
|
+
params: [
|
|
85485
|
+
{ name: "market", type: "string", required: false, description: "Kamino market address", default: "main market" },
|
|
85486
|
+
{ name: "token", type: "string", required: false, description: "Query a single token by symbol or mint address instead of the default SOL/USDC/USDT set" }
|
|
85487
|
+
]
|
|
85370
85488
|
}
|
|
85371
85489
|
];
|
|
85372
85490
|
var kaminoPlugin = {
|
|
@@ -85374,6 +85492,7 @@ var kaminoPlugin = {
|
|
|
85374
85492
|
name: "Kamino Lend",
|
|
85375
85493
|
createCommand() {
|
|
85376
85494
|
const cmd = new Command("kamino").description("Kamino Lend \u2014 deposit, withdraw, yield status");
|
|
85495
|
+
cmd.addCommand(createKaminoReservesCommand());
|
|
85377
85496
|
cmd.addCommand(createKaminoDepositCommand());
|
|
85378
85497
|
cmd.addCommand(createKaminoWithdrawCommand());
|
|
85379
85498
|
cmd.addCommand(createKaminoStatusCommand());
|