@byreal-io/byreal-cli-realclaw 0.3.2 → 0.3.4
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 +3 -2
- package/dist/index.cjs +306 -47
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ npm install -g @byreal-io/byreal-cli-realclaw
|
|
|
24
24
|
|
|
25
25
|
## Features
|
|
26
26
|
|
|
27
|
-
- **Pools** — List, search, and inspect CLMM pools. View K-line charts, APR, TVL, volume, and run comprehensive pool analysis (risk, volatility, range recommendations).
|
|
27
|
+
- **Pools** — List, search, and inspect CLMM pools. View K-line charts, Est. APR (fee + reward incentive breakdown), TVL, volume, and run comprehensive pool analysis (risk, volatility, range recommendations).
|
|
28
28
|
- **Tokens** — List tokens, search by symbol/name, get real-time prices.
|
|
29
29
|
- **Swap** — Preview and execute token swaps with slippage control and price impact estimation.
|
|
30
30
|
- **Positions** — Open, close, and manage CLMM positions. Claim fees and rewards. Analyze position performance. Copy top farmers' positions with one command.
|
|
@@ -66,7 +66,7 @@ All commands support `-o json` for structured output.
|
|
|
66
66
|
| `pools analyze` | Comprehensive pool analysis (APR, risk, range) |
|
|
67
67
|
| `tokens list` | List available tokens |
|
|
68
68
|
| `swap execute` | Preview or execute a token swap |
|
|
69
|
-
| `positions list` | List
|
|
69
|
+
| `positions list` | List positions (own wallet or any via --user) |
|
|
70
70
|
| `positions open` | Open a new CLMM position |
|
|
71
71
|
| `positions increase` | Add liquidity to an existing position |
|
|
72
72
|
| `positions decrease` | Partially remove liquidity from a position |
|
|
@@ -74,6 +74,7 @@ All commands support `-o json` for structured output.
|
|
|
74
74
|
| `positions claim` | Claim trading fees |
|
|
75
75
|
| `positions claim-rewards` | Claim incentive rewards from positions |
|
|
76
76
|
| `positions claim-bonus` | Claim CopyFarmer bonus rewards |
|
|
77
|
+
| `positions submit-rewards` | Submit signed reward/bonus transactions to backend |
|
|
77
78
|
| `positions analyze` | Analyze an existing position |
|
|
78
79
|
| `positions top-positions` | View top positions in a pool |
|
|
79
80
|
| `positions copy` | Copy a farmer's position |
|
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.4" : 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";
|
|
@@ -3061,6 +3061,7 @@ var init_constants = __esm({
|
|
|
3061
3061
|
// Reward / Bonus claim endpoints
|
|
3062
3062
|
UNCLAIMED_DATA: "/byreal/api/dex/v2/position/unclaimed-data",
|
|
3063
3063
|
REWARD_ENCODE: "/byreal/api/dex/v2/incentive/encode-v2",
|
|
3064
|
+
REWARD_ORDER: "/byreal/api/dex/v2/incentive/order-v2",
|
|
3064
3065
|
// Fee endpoints
|
|
3065
3066
|
AUTO_FEE: "/byreal/api/dex/v2/main/auto-fee"
|
|
3066
3067
|
};
|
|
@@ -82379,12 +82380,48 @@ var apiClient = {
|
|
|
82379
82380
|
// src/api/endpoints.ts
|
|
82380
82381
|
init_constants();
|
|
82381
82382
|
init_errors();
|
|
82383
|
+
function transformReward(r) {
|
|
82384
|
+
const isNewFormat = r.token !== void 0;
|
|
82385
|
+
const mintInfo = isNewFormat ? r.token?.mintInfo : r.mint;
|
|
82386
|
+
const mint = mintInfo?.address || "";
|
|
82387
|
+
const symbol = mintInfo?.symbol || "";
|
|
82388
|
+
const priceUsd = isNewFormat ? parseFloat(r.token?.price || "0") : 0;
|
|
82389
|
+
const apr = parseFloat(r.apr || "0") * 100;
|
|
82390
|
+
const rawEndTime = isNewFormat ? r.endTimestamp || 0 : r.rewardEndTime || 0;
|
|
82391
|
+
const endTime = rawEndTime > 1e12 ? Math.floor(rawEndTime / 1e3) : rawEndTime;
|
|
82392
|
+
const rawOpenTime = r.rewardOpenTime || 0;
|
|
82393
|
+
const openTime = rawOpenTime > 1e12 ? Math.floor(rawOpenTime / 1e3) : rawOpenTime;
|
|
82394
|
+
let dailyAmount = r.dailyAmountDisplay || r.dailyMaxAmount || "";
|
|
82395
|
+
if (!dailyAmount && r.rewardPerSecond) {
|
|
82396
|
+
const rps = parseFloat(r.rewardPerSecond);
|
|
82397
|
+
if (rps > 0) {
|
|
82398
|
+
dailyAmount = (rps * 86400).toString();
|
|
82399
|
+
}
|
|
82400
|
+
}
|
|
82401
|
+
const dailyAmountNum = parseFloat(dailyAmount || "0");
|
|
82402
|
+
const dailyAmountUsd = dailyAmountNum * priceUsd;
|
|
82403
|
+
return {
|
|
82404
|
+
mint,
|
|
82405
|
+
symbol,
|
|
82406
|
+
rewardPerSecond: r.rewardPerSecond || "0",
|
|
82407
|
+
openTime,
|
|
82408
|
+
endTime,
|
|
82409
|
+
apr,
|
|
82410
|
+
daily_amount: dailyAmount,
|
|
82411
|
+
daily_amount_usd: dailyAmountUsd,
|
|
82412
|
+
price_usd: priceUsd
|
|
82413
|
+
};
|
|
82414
|
+
}
|
|
82382
82415
|
function transformPool(apiPool) {
|
|
82383
82416
|
const mintA = apiPool.mintA?.mintInfo || {};
|
|
82384
82417
|
const mintB = apiPool.mintB?.mintInfo || {};
|
|
82385
82418
|
const baseMintPrice = parseFloat(apiPool.baseMint?.price || apiPool.mintA?.price || "0");
|
|
82386
82419
|
const quoteMintPrice = parseFloat(apiPool.quoteMint?.price || apiPool.mintB?.price || "0");
|
|
82387
82420
|
const poolPrice = quoteMintPrice > 0 ? baseMintPrice / quoteMintPrice : 0;
|
|
82421
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
82422
|
+
const activeRewards = (apiPool.rewards || []).map(transformReward).filter((r) => r.endTime > now || r.endTime === 0);
|
|
82423
|
+
const feeApr = parseFloat(apiPool.feeApr24h || "0") * 100;
|
|
82424
|
+
const rewardApr = activeRewards.reduce((sum3, r) => sum3 + r.apr, 0);
|
|
82388
82425
|
return {
|
|
82389
82426
|
id: apiPool.poolAddress,
|
|
82390
82427
|
pair: `${mintA.symbol || "Unknown"}/${mintB.symbol || "Unknown"}`,
|
|
@@ -82410,13 +82447,15 @@ function transformPool(apiPool) {
|
|
|
82410
82447
|
fee_rate_bps: parseInt(apiPool.feeRate?.fixFeeRate || "0", 10) / 100,
|
|
82411
82448
|
// fixFeeRate is in 1/100 bps
|
|
82412
82449
|
fee_24h_usd: parseFloat(apiPool.feeUsd1d || apiPool.feeUsd24h || "0"),
|
|
82413
|
-
apr:
|
|
82414
|
-
|
|
82450
|
+
apr: feeApr,
|
|
82451
|
+
reward_apr: rewardApr,
|
|
82452
|
+
total_apr: feeApr + rewardApr,
|
|
82415
82453
|
current_price: poolPrice,
|
|
82416
82454
|
created_at: apiPool.openTime ? new Date(apiPool.openTime).toISOString() : "",
|
|
82417
82455
|
price_change_1h: apiPool.priceChange1h ? parseFloat(apiPool.priceChange1h) * 100 : void 0,
|
|
82418
82456
|
price_change_24h: apiPool.priceChange1d ? parseFloat(apiPool.priceChange1d) * 100 : void 0,
|
|
82419
|
-
price_change_7d: apiPool.priceChange7d ? parseFloat(apiPool.priceChange7d) * 100 : void 0
|
|
82457
|
+
price_change_7d: apiPool.priceChange7d ? parseFloat(apiPool.priceChange7d) * 100 : void 0,
|
|
82458
|
+
rewards: activeRewards.length > 0 ? activeRewards : void 0
|
|
82420
82459
|
};
|
|
82421
82460
|
}
|
|
82422
82461
|
function transformToken(apiToken) {
|
|
@@ -82504,13 +82543,6 @@ async function getPoolInfo(poolId) {
|
|
|
82504
82543
|
};
|
|
82505
82544
|
}
|
|
82506
82545
|
const pool = transformPool(poolData);
|
|
82507
|
-
const rewards = (poolData.rewards || []).map((r) => ({
|
|
82508
|
-
mint: r.mint?.address || "",
|
|
82509
|
-
symbol: r.mint?.symbol || "",
|
|
82510
|
-
rewardPerSecond: r.rewardPerSecond || "0",
|
|
82511
|
-
openTime: r.rewardOpenTime || 0,
|
|
82512
|
-
endTime: r.rewardEndTime || 0
|
|
82513
|
-
}));
|
|
82514
82546
|
return {
|
|
82515
82547
|
ok: true,
|
|
82516
82548
|
value: {
|
|
@@ -82523,8 +82555,7 @@ async function getPoolInfo(poolId) {
|
|
|
82523
82555
|
price_change_24h: parseFloat(poolData.priceChange1d || "0") * 100,
|
|
82524
82556
|
price_change_7d: parseFloat(poolData.priceChange7d || "0") * 100,
|
|
82525
82557
|
fee_7d_usd: parseFloat(poolData.feeUsd7d || "0"),
|
|
82526
|
-
category: poolData.category
|
|
82527
|
-
rewards: rewards.length > 0 ? rewards : void 0
|
|
82558
|
+
category: poolData.category
|
|
82528
82559
|
}
|
|
82529
82560
|
};
|
|
82530
82561
|
}
|
|
@@ -82846,6 +82877,19 @@ async function encodeReward(params) {
|
|
|
82846
82877
|
}
|
|
82847
82878
|
return { ok: true, value: data };
|
|
82848
82879
|
}
|
|
82880
|
+
async function submitRewardOrder(params) {
|
|
82881
|
+
const result = await apiClient.post(API_ENDPOINTS.REWARD_ORDER, {
|
|
82882
|
+
orderCode: params.orderCode,
|
|
82883
|
+
walletAddress: params.walletAddress,
|
|
82884
|
+
signedTxPayload: params.signedTxPayload
|
|
82885
|
+
});
|
|
82886
|
+
if (!result.ok) return result;
|
|
82887
|
+
const data = result.value.result?.data;
|
|
82888
|
+
if (!data) {
|
|
82889
|
+
return { ok: true, value: { orderCode: "", txList: [], claimTokenList: [] } };
|
|
82890
|
+
}
|
|
82891
|
+
return { ok: true, value: data };
|
|
82892
|
+
}
|
|
82849
82893
|
var api = {
|
|
82850
82894
|
listPools,
|
|
82851
82895
|
getPoolInfo,
|
|
@@ -82860,7 +82904,8 @@ var api = {
|
|
|
82860
82904
|
getUnclaimedData,
|
|
82861
82905
|
getEpochBonus,
|
|
82862
82906
|
getProviderOverview,
|
|
82863
|
-
encodeReward
|
|
82907
|
+
encodeReward,
|
|
82908
|
+
submitRewardOrder
|
|
82864
82909
|
};
|
|
82865
82910
|
|
|
82866
82911
|
// src/cli/commands/pools.ts
|
|
@@ -82953,20 +82998,26 @@ function formatApr(value) {
|
|
|
82953
82998
|
return color(`${value.toFixed(2)}%`);
|
|
82954
82999
|
}
|
|
82955
83000
|
function outputPoolsTable(pools, total) {
|
|
82956
|
-
const table = createTable(["Pair", "Pool ID", "TVL", "Volume 24h", "APR", "Fee Rate"]);
|
|
83001
|
+
const table = createTable(["Pair", "Pool ID", "TVL", "Volume 24h", "Est. APR", "Fee Rate"]);
|
|
82957
83002
|
for (const pool of pools) {
|
|
83003
|
+
const hasRewards = pool.reward_apr > 0;
|
|
83004
|
+
const aprDisplay = formatApr(pool.total_apr) + (hasRewards ? source_default.magenta(" (+R)") : "");
|
|
82958
83005
|
table.push([
|
|
82959
83006
|
source_default.white.bold(pool.pair),
|
|
82960
83007
|
source_default.gray(pool.id),
|
|
82961
83008
|
formatUsd(pool.tvl_usd),
|
|
82962
83009
|
formatUsd(pool.volume_24h_usd),
|
|
82963
|
-
|
|
83010
|
+
aprDisplay,
|
|
82964
83011
|
`${(pool.fee_rate_bps / 100).toFixed(2)}%`
|
|
82965
83012
|
]);
|
|
82966
83013
|
}
|
|
82967
83014
|
console.log(table.toString());
|
|
82968
83015
|
console.log(source_default.gray(`
|
|
82969
83016
|
Showing ${pools.length} of ${total} pools`));
|
|
83017
|
+
const hasAnyRewards = pools.some((p) => p.reward_apr > 0);
|
|
83018
|
+
if (hasAnyRewards) {
|
|
83019
|
+
console.log(source_default.magenta("(+R)") + source_default.gray(" = includes reward incentives"));
|
|
83020
|
+
}
|
|
82970
83021
|
}
|
|
82971
83022
|
function outputPoolDetail(pool) {
|
|
82972
83023
|
console.log(source_default.cyan.bold(`
|
|
@@ -82980,9 +83031,26 @@ ${pool.pair}`));
|
|
|
82980
83031
|
["Volume (7d)", formatUsd(pool.volume_7d_usd)],
|
|
82981
83032
|
["Fees (24h)", formatUsd(pool.fee_24h_usd)],
|
|
82982
83033
|
["Fee Rate", `${(pool.fee_rate_bps / 100).toFixed(2)}%`],
|
|
82983
|
-
["APR", formatApr(pool.apr)]
|
|
83034
|
+
["Fee APR", formatApr(pool.apr)],
|
|
83035
|
+
["Reward APR", pool.reward_apr > 0 ? formatApr(pool.reward_apr) : source_default.gray("None")],
|
|
83036
|
+
["Total APR", source_default.bold(formatApr(pool.total_apr))]
|
|
82984
83037
|
);
|
|
82985
83038
|
console.log(table.toString());
|
|
83039
|
+
if (pool.rewards && pool.rewards.length > 0) {
|
|
83040
|
+
console.log(source_default.cyan("\nActive Rewards:"));
|
|
83041
|
+
const rewardsTable = createTable(["Token", "APR", "Daily Amount", "Daily USD", "Ends"]);
|
|
83042
|
+
for (const r of pool.rewards) {
|
|
83043
|
+
const endDate = r.endTime > 0 ? new Date(r.endTime * 1e3).toISOString().slice(0, 10) : "Ongoing";
|
|
83044
|
+
rewardsTable.push([
|
|
83045
|
+
source_default.white.bold(r.symbol || r.mint),
|
|
83046
|
+
formatApr(r.apr),
|
|
83047
|
+
r.daily_amount ? parseFloat(r.daily_amount).toLocaleString() : "-",
|
|
83048
|
+
r.daily_amount_usd > 0 ? formatUsd(r.daily_amount_usd) : "-",
|
|
83049
|
+
source_default.gray(endDate)
|
|
83050
|
+
]);
|
|
83051
|
+
}
|
|
83052
|
+
console.log(rewardsTable.toString());
|
|
83053
|
+
}
|
|
82986
83054
|
console.log(source_default.cyan("\nPrices:"));
|
|
82987
83055
|
const priceTable = createTable(["Token", "Price (USD)", "Mint"]);
|
|
82988
83056
|
priceTable.push(
|
|
@@ -83412,6 +83480,8 @@ Pool Analysis: ${data.pool.pair}`));
|
|
|
83412
83480
|
["Fees (24h)", `$${data.metrics.fee24h}`],
|
|
83413
83481
|
["Fees (7d)", `$${data.metrics.fee7d}`],
|
|
83414
83482
|
["Fee APR (24h)", data.metrics.feeApr24h],
|
|
83483
|
+
["Reward APR", data.metrics.rewardApr || source_default.gray("None")],
|
|
83484
|
+
["Total APR", source_default.bold(data.metrics.totalApr)],
|
|
83415
83485
|
["Volume/TVL", data.metrics.volumeToTvl]
|
|
83416
83486
|
);
|
|
83417
83487
|
console.log(metricsTable.toString());
|
|
@@ -83424,9 +83494,15 @@ Pool Analysis: ${data.pool.pair}`));
|
|
|
83424
83494
|
console.log(volTable.toString());
|
|
83425
83495
|
if (data.rewards && data.rewards.length > 0) {
|
|
83426
83496
|
console.log(source_default.cyan.bold("\nRewards"));
|
|
83427
|
-
const rewardsTable = createTable(["Token", "End Date"]);
|
|
83497
|
+
const rewardsTable = createTable(["Token", "APR", "Daily Amount", "Daily USD", "End Date"]);
|
|
83428
83498
|
for (const r of data.rewards) {
|
|
83429
|
-
rewardsTable.push([
|
|
83499
|
+
rewardsTable.push([
|
|
83500
|
+
r.token,
|
|
83501
|
+
r.apr || "-",
|
|
83502
|
+
r.dailyAmount || "-",
|
|
83503
|
+
r.dailyAmountUsd || "-",
|
|
83504
|
+
r.endTime
|
|
83505
|
+
]);
|
|
83430
83506
|
}
|
|
83431
83507
|
console.log(rewardsTable.toString());
|
|
83432
83508
|
}
|
|
@@ -83555,6 +83631,25 @@ function outputError(error, format) {
|
|
|
83555
83631
|
outputErrorTable(error);
|
|
83556
83632
|
}
|
|
83557
83633
|
}
|
|
83634
|
+
function outputRewardOrderResult(result) {
|
|
83635
|
+
console.log(source_default.green.bold("\nRewards Claimed\n"));
|
|
83636
|
+
if (result.claimTokenList.length > 0) {
|
|
83637
|
+
console.log(source_default.white.bold(" Claimed Tokens:"));
|
|
83638
|
+
for (const token of result.claimTokenList) {
|
|
83639
|
+
console.log(source_default.gray(` ${token.tokenAmount} ${token.tokenSymbol} (${token.tokenAddress})`));
|
|
83640
|
+
}
|
|
83641
|
+
console.log();
|
|
83642
|
+
}
|
|
83643
|
+
if (result.txList.length > 0) {
|
|
83644
|
+
console.log(source_default.white.bold(" Transactions:"));
|
|
83645
|
+
for (const tx of result.txList) {
|
|
83646
|
+
const statusLabel = tx.status === 1 ? source_default.green("Success") : tx.status === 2 ? source_default.red("Failed") : source_default.yellow("Sent");
|
|
83647
|
+
console.log(source_default.gray(` ${tx.txSignature} ${statusLabel}`));
|
|
83648
|
+
console.log(source_default.blue(` https://solscan.io/tx/${tx.txSignature}`));
|
|
83649
|
+
}
|
|
83650
|
+
console.log();
|
|
83651
|
+
}
|
|
83652
|
+
}
|
|
83558
83653
|
|
|
83559
83654
|
// src/cli/commands/pools.ts
|
|
83560
83655
|
async function listPools2(options, globalOptions) {
|
|
@@ -83759,14 +83854,15 @@ function createPoolsAnalyzeCommand() {
|
|
|
83759
83854
|
const dayPriceLow = pool.price_range_24h.low;
|
|
83760
83855
|
const dayPriceHigh = pool.price_range_24h.high;
|
|
83761
83856
|
const dayPriceRangePercent = currentPrice > 0 ? (dayPriceHigh - dayPriceLow) / currentPrice * 100 : 0;
|
|
83762
|
-
const
|
|
83763
|
-
const
|
|
83764
|
-
|
|
83765
|
-
|
|
83766
|
-
|
|
83767
|
-
|
|
83768
|
-
}
|
|
83769
|
-
|
|
83857
|
+
const activeRewards = pool.rewards || [];
|
|
83858
|
+
const totalRewardApr = pool.reward_apr;
|
|
83859
|
+
const rewardsOutput = activeRewards.map((r) => ({
|
|
83860
|
+
token: r.symbol || r.mint,
|
|
83861
|
+
apr: `${r.apr.toFixed(2)}%`,
|
|
83862
|
+
dailyAmount: r.daily_amount ? parseFloat(r.daily_amount).toLocaleString() : "-",
|
|
83863
|
+
dailyAmountUsd: r.daily_amount_usd > 0 ? `$${r.daily_amount_usd.toFixed(2)}` : "-",
|
|
83864
|
+
endTime: r.endTime > 0 ? new Date(r.endTime * 1e3).toISOString().slice(0, 10) : "Ongoing"
|
|
83865
|
+
}));
|
|
83770
83866
|
const rangeAprs = calculateRangeAprs2({
|
|
83771
83867
|
percentRanges: rangePercents,
|
|
83772
83868
|
volume24h: pool.volume_24h_usd,
|
|
@@ -83816,8 +83912,7 @@ function createPoolsAnalyzeCommand() {
|
|
|
83816
83912
|
priceLower: alignedPriceLower.toFixed(8).replace(/0+$/, "").replace(/\.$/, ""),
|
|
83817
83913
|
priceUpper: alignedPriceUpper.toFixed(8).replace(/0+$/, "").replace(/\.$/, ""),
|
|
83818
83914
|
estimatedFeeApr: `${feeApr.toFixed(1)}%`,
|
|
83819
|
-
estimatedTotalApr: `${feeApr.toFixed(1)}%`,
|
|
83820
|
-
// same as feeApr if no rewards calculated
|
|
83915
|
+
estimatedTotalApr: `${(feeApr + totalRewardApr).toFixed(1)}%`,
|
|
83821
83916
|
inRangeLikelihood,
|
|
83822
83917
|
rebalanceFrequency
|
|
83823
83918
|
};
|
|
@@ -83826,7 +83921,7 @@ function createPoolsAnalyzeCommand() {
|
|
|
83826
83921
|
const volatilityRisk = assessVolatilityRisk(dayPriceRangePercent);
|
|
83827
83922
|
const riskSummary = buildRiskSummary(pool, dayPriceRangePercent);
|
|
83828
83923
|
const projectionRange = rangePercents.includes(10) ? 10 : rangePercents[Math.floor(rangePercents.length / 2)];
|
|
83829
|
-
const projectionApr = rangeAprs[projectionRange] || 0;
|
|
83924
|
+
const projectionApr = (rangeAprs[projectionRange] || 0) + totalRewardApr;
|
|
83830
83925
|
const dailyFee = projectionApr / 100 / 365 * investAmount;
|
|
83831
83926
|
const weeklyFee = dailyFee * 7;
|
|
83832
83927
|
const monthlyFee = dailyFee * 30;
|
|
@@ -83847,6 +83942,8 @@ function createPoolsAnalyzeCommand() {
|
|
|
83847
83942
|
fee24h: fee24h.toFixed(2),
|
|
83848
83943
|
fee7d: fee7d.toFixed(2),
|
|
83849
83944
|
feeApr24h: `${feeApr24h.toFixed(2)}%`,
|
|
83945
|
+
rewardApr: totalRewardApr > 0 ? `${totalRewardApr.toFixed(2)}%` : void 0,
|
|
83946
|
+
totalApr: `${(feeApr24h + totalRewardApr).toFixed(2)}%`,
|
|
83850
83947
|
volumeToTvl: volumeToTvl.toFixed(2)
|
|
83851
83948
|
},
|
|
83852
83949
|
volatility: {
|
|
@@ -84072,7 +84169,7 @@ byreal-cli catalog show dex.pool.list
|
|
|
84072
84169
|
| dex.token.list | Query tokens with search |
|
|
84073
84170
|
| dex.overview.global | Global statistics |
|
|
84074
84171
|
| dex.swap.execute | Preview or execute a token swap |
|
|
84075
|
-
| dex.position.list | List
|
|
84172
|
+
| dex.position.list | List positions for your wallet or any wallet via --user |
|
|
84076
84173
|
| dex.position.analyze | Analyze existing position |
|
|
84077
84174
|
| dex.position.open | Open a new CLMM position |
|
|
84078
84175
|
| dex.position.increase | Add liquidity to an existing position |
|
|
@@ -84187,7 +84284,7 @@ Byreal CLI provides on-chain data only. For complete analysis, **you (the AI age
|
|
|
84187
84284
|
## Commands
|
|
84188
84285
|
|
|
84189
84286
|
### pools list
|
|
84190
|
-
Query available liquidity pools with sorting and filtering.
|
|
84287
|
+
Query available liquidity pools with Est. APR (fee + reward incentive breakdown), sorting and filtering.
|
|
84191
84288
|
|
|
84192
84289
|
\`\`\`bash
|
|
84193
84290
|
byreal-cli pools list [options]
|
|
@@ -84214,7 +84311,7 @@ byreal-cli pools list --category 1 -o json
|
|
|
84214
84311
|
\`\`\`
|
|
84215
84312
|
|
|
84216
84313
|
### pools info
|
|
84217
|
-
Get detailed information about a specific pool.
|
|
84314
|
+
Get detailed information about a specific pool, including Fee APR, Reward APR, Total APR breakdown and active reward incentives (token, APR, daily amount, daily USD, end date).
|
|
84218
84315
|
|
|
84219
84316
|
\`\`\`bash
|
|
84220
84317
|
byreal-cli pools info <pool-id> -o json
|
|
@@ -84354,12 +84451,13 @@ byreal-cli swap execute --input-mint So11111111111111111111111111111111111111112
|
|
|
84354
84451
|
\`\`\`
|
|
84355
84452
|
|
|
84356
84453
|
### positions list
|
|
84357
|
-
List user's
|
|
84454
|
+
List CLMM positions for your wallet or any wallet address. Use \`--user\` to query another wallet's positions (read-only, no \`--wallet-address\` needed).
|
|
84358
84455
|
|
|
84359
84456
|
\`\`\`bash
|
|
84360
84457
|
byreal-cli positions list [options]
|
|
84361
84458
|
|
|
84362
84459
|
Options:
|
|
84460
|
+
--user <address> Query positions for a specific wallet address (read-only)
|
|
84363
84461
|
--page <n> Page number (default: 1)
|
|
84364
84462
|
--page-size <n> Page size (default: 20)
|
|
84365
84463
|
--sort-field <field> Sort field
|
|
@@ -84368,6 +84466,18 @@ Options:
|
|
|
84368
84466
|
--status <status> Filter by status: 0=closed, 1=active
|
|
84369
84467
|
\`\`\`
|
|
84370
84468
|
|
|
84469
|
+
Examples:
|
|
84470
|
+
\`\`\`bash
|
|
84471
|
+
# List your own positions
|
|
84472
|
+
byreal-cli positions list --wallet-address <your-addr> -o json
|
|
84473
|
+
|
|
84474
|
+
# Query another user's positions (for LP copy trading research)
|
|
84475
|
+
byreal-cli positions list --user <target-wallet> -o json
|
|
84476
|
+
|
|
84477
|
+
# Query another user's positions in a specific pool
|
|
84478
|
+
byreal-cli positions list --user <target-wallet> --pool <pool-address> -o json
|
|
84479
|
+
\`\`\`
|
|
84480
|
+
|
|
84371
84481
|
### positions open
|
|
84372
84482
|
Open a new CLMM position. Supports two modes: specify token amount (--amount) or USD investment (--amount-usd).
|
|
84373
84483
|
|
|
@@ -84502,6 +84612,9 @@ Options:
|
|
|
84502
84612
|
- **Incentive rewards** \u2192 \`positions claim-rewards\` (this command)
|
|
84503
84613
|
- **Copy bonus** \u2192 \`positions claim-bonus\` (see below)
|
|
84504
84614
|
|
|
84615
|
+
**IMPORTANT \u2014 claim-rewards is a multi-step flow:**
|
|
84616
|
+
The output includes \`orderCode\` and per-transaction \`txCode\`. After the wallet signs each transaction, you MUST call \`positions submit-rewards\` to send the signed transactions back to the backend for broadcasting. See "Workflow: Claim Rewards / Bonus" below.
|
|
84617
|
+
|
|
84505
84618
|
### positions claim-bonus
|
|
84506
84619
|
Claim CopyFarmer bonus rewards earned from copying other users' positions. Bonuses accrue in epochs and become claimable in time windows.
|
|
84507
84620
|
|
|
@@ -84517,6 +84630,24 @@ Options:
|
|
|
84517
84630
|
- **Pending**: Settlement period, not yet claimable
|
|
84518
84631
|
- **Claimable**: Ready to claim within the time window
|
|
84519
84632
|
|
|
84633
|
+
**IMPORTANT \u2014 claim-bonus is a multi-step flow** (same as claim-rewards): After signing, call \`positions submit-rewards\` to complete the claim.
|
|
84634
|
+
|
|
84635
|
+
### positions submit-rewards
|
|
84636
|
+
Submit signed reward/bonus claim transactions to the backend for on-chain broadcasting. This is the final step after \`claim-rewards\` or \`claim-bonus\` generates unsigned transactions and the wallet signs them.
|
|
84637
|
+
|
|
84638
|
+
\`\`\`bash
|
|
84639
|
+
byreal-cli positions submit-rewards [options]
|
|
84640
|
+
|
|
84641
|
+
Options:
|
|
84642
|
+
--order-code <code> Order code from claim-rewards or claim-bonus output (required)
|
|
84643
|
+
--signed-payloads <json> JSON array of signed transactions (required)
|
|
84644
|
+
\`\`\`
|
|
84645
|
+
|
|
84646
|
+
The \`--signed-payloads\` format:
|
|
84647
|
+
\`\`\`json
|
|
84648
|
+
[{"txCode":"<from output>","poolAddress":"<from output>","signedTx":"<base64 signed tx>"}]
|
|
84649
|
+
\`\`\`
|
|
84650
|
+
|
|
84520
84651
|
### positions top-positions
|
|
84521
84652
|
Query top positions in a pool. Use this to discover high-performing positions that can be copied.
|
|
84522
84653
|
Each position includes an \`inRange\` field (true/false) indicating whether the pool's current tick is within the position's tick range. Out-of-range positions earn zero trading fees.
|
|
@@ -84561,7 +84692,7 @@ Response includes:
|
|
|
84561
84692
|
- **pool**: Basic info (address, pair, category, currentPrice, feeRate, tickSpacing)
|
|
84562
84693
|
- **metrics**: TVL, volume (24h/7d), fees (24h/7d), feeApr24h, volumeToTvl ratio
|
|
84563
84694
|
- **volatility**: 24h price range (low/high) and dayPriceRangePercent
|
|
84564
|
-
- **rewards**: Active reward programs (token,
|
|
84695
|
+
- **rewards**: Active reward programs (token, APR, daily amount, daily USD value, end date)
|
|
84565
84696
|
- **rangeAnalysis**: For each range %, shows priceLower/Upper, estimated fee APR, in-range likelihood, rebalance frequency
|
|
84566
84697
|
- **riskFactors**: TVL risk, volatility risk, and human-readable summary
|
|
84567
84698
|
- **wallet**: Wallet address, balanceUsd, and optional low-balance warning (included when --wallet-address is provided)
|
|
@@ -84693,6 +84824,43 @@ When user asks vague questions like "\u6709\u4EC0\u4E48\u4ED3\u4F4D\u53EF\u4EE5
|
|
|
84693
84824
|
- Always explain WHY you recommend a position (e.g., "\u9AD8\u624B\u7EED\u8D39\u6536\u76CA + \u4F4E\u65E0\u5E38\u635F\u5931 + \u5728\u533A\u95F4\u5185")
|
|
84694
84825
|
- If user's balance is low (<$20), suggest starting with a single position to minimize gas cost
|
|
84695
84826
|
- If all positions in a pool are out-of-range, skip that pool and explain why
|
|
84827
|
+
- To inspect a specific LP's full portfolio: \`byreal-cli positions list --user <wallet-address> -o json\`
|
|
84828
|
+
|
|
84829
|
+
## Workflow: Claim Rewards / Bonus (Multi-Step)
|
|
84830
|
+
|
|
84831
|
+
Claiming incentive rewards (\`claim-rewards\`) and CopyFarmer bonus (\`claim-bonus\`) requires a **3-step flow** because the backend co-signs and broadcasts these transactions:
|
|
84832
|
+
|
|
84833
|
+
**Step 1 \u2014 Preview** (optional but recommended):
|
|
84834
|
+
\`\`\`bash
|
|
84835
|
+
byreal-cli positions claim-rewards --dry-run --wallet-address <addr> -o json
|
|
84836
|
+
\`\`\`
|
|
84837
|
+
|
|
84838
|
+
**Step 2 \u2014 Generate unsigned transactions**:
|
|
84839
|
+
\`\`\`bash
|
|
84840
|
+
byreal-cli positions claim-rewards --wallet-address <addr> -o json
|
|
84841
|
+
\`\`\`
|
|
84842
|
+
Output:
|
|
84843
|
+
\`\`\`json
|
|
84844
|
+
{
|
|
84845
|
+
"orderCode": "ORD_xxx",
|
|
84846
|
+
"unsignedTransactions": [
|
|
84847
|
+
{ "poolAddress": "...", "txPayload": "<base64>", "txCode": "TX_xxx", "tokens": [...] }
|
|
84848
|
+
]
|
|
84849
|
+
}
|
|
84850
|
+
\`\`\`
|
|
84851
|
+
|
|
84852
|
+
**Step 3 \u2014 Sign each \`txPayload\` with the user's wallet**, then submit:
|
|
84853
|
+
\`\`\`bash
|
|
84854
|
+
byreal-cli positions submit-rewards \\
|
|
84855
|
+
--order-code "ORD_xxx" \\
|
|
84856
|
+
--signed-payloads '[{"txCode":"TX_xxx","poolAddress":"...","signedTx":"<base64 signed>"}]' \\
|
|
84857
|
+
--wallet-address <addr> -o json
|
|
84858
|
+
\`\`\`
|
|
84859
|
+
The backend broadcasts the signed transactions on-chain and returns tx signatures + status.
|
|
84860
|
+
|
|
84861
|
+
**For claim-bonus**: Same flow \u2014 replace \`claim-rewards\` with \`claim-bonus\` in Step 1-2; Step 3 is identical (\`submit-rewards\`).
|
|
84862
|
+
|
|
84863
|
+
**Critical**: Do NOT skip Step 3. Without \`submit-rewards\`, the signed transactions are never sent to the blockchain. The \`orderCode\` ties the encode and submit steps together \u2014 always pass the same \`orderCode\` from Step 2 into Step 3.
|
|
84696
84864
|
|
|
84697
84865
|
## Output Format
|
|
84698
84866
|
|
|
@@ -84809,7 +84977,7 @@ var CAPABILITIES = [
|
|
|
84809
84977
|
{
|
|
84810
84978
|
id: "dex.pool.list",
|
|
84811
84979
|
name: "List Pools",
|
|
84812
|
-
description: "Query available liquidity pools with sorting and filtering",
|
|
84980
|
+
description: "Query available liquidity pools with Est. APR (fee + reward incentive), sorting and filtering",
|
|
84813
84981
|
category: "query",
|
|
84814
84982
|
auth_required: false,
|
|
84815
84983
|
command: "byreal-cli pools list",
|
|
@@ -84850,7 +85018,7 @@ var CAPABILITIES = [
|
|
|
84850
85018
|
{
|
|
84851
85019
|
id: "dex.pool.analyze",
|
|
84852
85020
|
name: "Pool Analysis",
|
|
84853
|
-
description: "Comprehensive pool analysis: metrics, volatility, multi-range APR comparison, risk assessment, and investment projection",
|
|
85021
|
+
description: "Comprehensive pool analysis: metrics (fee APR, reward APR, total APR), volatility, multi-range APR comparison, risk assessment, and investment projection",
|
|
84854
85022
|
category: "analyze",
|
|
84855
85023
|
auth_required: false,
|
|
84856
85024
|
command: "byreal-cli pools analyze <pool-id>",
|
|
@@ -84945,11 +85113,12 @@ var CAPABILITIES = [
|
|
|
84945
85113
|
{
|
|
84946
85114
|
id: "dex.position.list",
|
|
84947
85115
|
name: "List Positions",
|
|
84948
|
-
description: "List
|
|
85116
|
+
description: "List CLMM positions for your wallet or any wallet address. Use --user to query another wallet (read-only, no --wallet-address needed).",
|
|
84949
85117
|
category: "query",
|
|
84950
|
-
auth_required:
|
|
84951
|
-
command: "byreal-cli positions list
|
|
85118
|
+
auth_required: false,
|
|
85119
|
+
command: "byreal-cli positions list",
|
|
84952
85120
|
params: [
|
|
85121
|
+
{ name: "user", type: "string", required: false, description: "Query positions for a specific wallet address (read-only)" },
|
|
84953
85122
|
{ name: "page", type: "integer", required: false, description: "Page number", default: "1" },
|
|
84954
85123
|
{ name: "page-size", type: "integer", required: false, description: "Page size", default: "20" },
|
|
84955
85124
|
{ name: "sort-field", type: "string", required: false, description: "Sort field" },
|
|
@@ -85067,6 +85236,18 @@ var CAPABILITIES = [
|
|
|
85067
85236
|
{ name: "dry-run", type: "boolean", required: false, description: "Preview claimable bonus without claiming" }
|
|
85068
85237
|
]
|
|
85069
85238
|
},
|
|
85239
|
+
{
|
|
85240
|
+
id: "dex.position.submitRewards",
|
|
85241
|
+
name: "Submit Signed Rewards",
|
|
85242
|
+
description: "Submit signed reward/bonus claim transactions to backend for broadcasting. Used after claim-rewards or claim-bonus generates unsigned transactions and the external wallet signs them. Requires --wallet-address global option.",
|
|
85243
|
+
category: "execute",
|
|
85244
|
+
auth_required: true,
|
|
85245
|
+
command: "byreal-cli positions submit-rewards --wallet-address <address>",
|
|
85246
|
+
params: [
|
|
85247
|
+
{ name: "order-code", type: "string", required: true, description: "Order code from claim-rewards or claim-bonus output" },
|
|
85248
|
+
{ name: "signed-payloads", type: "string", required: true, description: 'JSON array of signed transactions: [{"txCode":"...","poolAddress":"...","signedTx":"<base64>"}]' }
|
|
85249
|
+
]
|
|
85250
|
+
},
|
|
85070
85251
|
{
|
|
85071
85252
|
id: "dex.position.topPositions",
|
|
85072
85253
|
name: "Top Positions",
|
|
@@ -85620,25 +85801,31 @@ function serializeTransaction(tx) {
|
|
|
85620
85801
|
// src/cli/commands/positions.ts
|
|
85621
85802
|
init_errors();
|
|
85622
85803
|
function createPositionsListCommand() {
|
|
85623
|
-
return new Command("list").description("List your positions").option("--page <n>", "Page number", "1").option("--page-size <n>", "Page size", "20").option("--sort-field <field>", "Sort field").option("--sort-type <type>", "Sort direction: asc or desc").option("--pool <address>", "Filter by pool address").option(
|
|
85804
|
+
return new Command("list").description("List positions for your wallet or any wallet address").option("--user <address>", "Query positions for a specific wallet address (read-only, no --wallet-address needed)").option("--page <n>", "Page number", "1").option("--page-size <n>", "Page size", "20").option("--sort-field <field>", "Sort field").option("--sort-type <type>", "Sort direction: asc or desc").option("--pool <address>", "Filter by pool address").option(
|
|
85624
85805
|
"--status <status>",
|
|
85625
85806
|
"Filter by status: 0=active, 1=closed (default: 0)"
|
|
85626
85807
|
).action(async (options, cmdObj) => {
|
|
85627
85808
|
const globalOptions = cmdObj.optsWithGlobals();
|
|
85628
85809
|
const format = globalOptions.output;
|
|
85629
85810
|
const startTime = Date.now();
|
|
85630
|
-
const
|
|
85631
|
-
if (!
|
|
85632
|
-
const
|
|
85811
|
+
const userAddress = options.user || globalOptions.walletAddress;
|
|
85812
|
+
if (!userAddress) {
|
|
85813
|
+
const errMsg = "Provide --user <address> or global --wallet-address to specify which wallet to query.";
|
|
85633
85814
|
if (format === "json") {
|
|
85634
|
-
outputErrorJson(
|
|
85815
|
+
outputErrorJson({ code: "MISSING_ADDRESS", type: "VALIDATION", message: errMsg, retryable: false });
|
|
85635
85816
|
} else {
|
|
85636
|
-
|
|
85817
|
+
console.error(source_default.red(`
|
|
85818
|
+
Error: ${errMsg}`));
|
|
85637
85819
|
}
|
|
85638
85820
|
process.exit(1);
|
|
85639
85821
|
}
|
|
85822
|
+
if (options.user && format !== "json") {
|
|
85823
|
+
console.log(source_default.gray(`
|
|
85824
|
+
Positions for: ${options.user}
|
|
85825
|
+
`));
|
|
85826
|
+
}
|
|
85640
85827
|
const result = await api.listPositions({
|
|
85641
|
-
userAddress
|
|
85828
|
+
userAddress,
|
|
85642
85829
|
page: parseInt(options.page, 10),
|
|
85643
85830
|
pageSize: parseInt(options.pageSize, 10),
|
|
85644
85831
|
sortField: options.sortField,
|
|
@@ -87500,6 +87687,77 @@ SDK Error: ${message}`));
|
|
|
87500
87687
|
}
|
|
87501
87688
|
});
|
|
87502
87689
|
}
|
|
87690
|
+
function createSubmitRewardsCommand() {
|
|
87691
|
+
return new Command("submit-rewards").description(
|
|
87692
|
+
"Submit signed reward/bonus transactions to backend for broadcasting"
|
|
87693
|
+
).requiredOption(
|
|
87694
|
+
"--order-code <code>",
|
|
87695
|
+
"Order code from claim-rewards or claim-bonus output"
|
|
87696
|
+
).requiredOption(
|
|
87697
|
+
"--signed-payloads <json>",
|
|
87698
|
+
'JSON array: [{"txCode":"...","poolAddress":"...","signedTx":"<base64>"}]'
|
|
87699
|
+
).action(async (options, cmdObj) => {
|
|
87700
|
+
const globalOptions = cmdObj.optsWithGlobals();
|
|
87701
|
+
const format = globalOptions.output;
|
|
87702
|
+
const startTime = Date.now();
|
|
87703
|
+
const walletAddress = globalOptions.walletAddress;
|
|
87704
|
+
if (!walletAddress) {
|
|
87705
|
+
const err2 = missingWalletAddressError();
|
|
87706
|
+
if (format === "json") {
|
|
87707
|
+
outputErrorJson(err2.toJSON());
|
|
87708
|
+
} else {
|
|
87709
|
+
outputErrorTable(err2.toJSON());
|
|
87710
|
+
}
|
|
87711
|
+
process.exit(1);
|
|
87712
|
+
}
|
|
87713
|
+
let signedPayloads;
|
|
87714
|
+
try {
|
|
87715
|
+
signedPayloads = JSON.parse(options.signedPayloads);
|
|
87716
|
+
if (!Array.isArray(signedPayloads) || signedPayloads.length === 0) {
|
|
87717
|
+
throw new Error("must be a non-empty array");
|
|
87718
|
+
}
|
|
87719
|
+
for (const p of signedPayloads) {
|
|
87720
|
+
if (!p.txCode || !p.poolAddress || !p.signedTx) {
|
|
87721
|
+
throw new Error(
|
|
87722
|
+
"each entry must have txCode, poolAddress, signedTx"
|
|
87723
|
+
);
|
|
87724
|
+
}
|
|
87725
|
+
}
|
|
87726
|
+
} catch (e) {
|
|
87727
|
+
const errMsg = `Invalid --signed-payloads: ${e.message}`;
|
|
87728
|
+
if (format === "json") {
|
|
87729
|
+
outputErrorJson({
|
|
87730
|
+
code: "INVALID_PARAMETER",
|
|
87731
|
+
type: "VALIDATION",
|
|
87732
|
+
message: errMsg,
|
|
87733
|
+
retryable: false
|
|
87734
|
+
});
|
|
87735
|
+
} else {
|
|
87736
|
+
console.error(source_default.red(`
|
|
87737
|
+
Error: ${errMsg}`));
|
|
87738
|
+
}
|
|
87739
|
+
process.exit(1);
|
|
87740
|
+
}
|
|
87741
|
+
const orderResult = await api.submitRewardOrder({
|
|
87742
|
+
orderCode: options.orderCode,
|
|
87743
|
+
walletAddress,
|
|
87744
|
+
signedTxPayload: signedPayloads
|
|
87745
|
+
});
|
|
87746
|
+
if (!orderResult.ok) {
|
|
87747
|
+
if (format === "json") {
|
|
87748
|
+
outputErrorJson(orderResult.error);
|
|
87749
|
+
} else {
|
|
87750
|
+
outputErrorTable(orderResult.error);
|
|
87751
|
+
}
|
|
87752
|
+
process.exit(1);
|
|
87753
|
+
}
|
|
87754
|
+
if (format === "json") {
|
|
87755
|
+
outputJson(orderResult.value, startTime);
|
|
87756
|
+
} else {
|
|
87757
|
+
outputRewardOrderResult(orderResult.value);
|
|
87758
|
+
}
|
|
87759
|
+
});
|
|
87760
|
+
}
|
|
87503
87761
|
function createPositionsCommand() {
|
|
87504
87762
|
const cmd = new Command("positions").description("Manage CLMM positions");
|
|
87505
87763
|
cmd.addCommand(createPositionsListCommand());
|
|
@@ -87510,6 +87768,7 @@ function createPositionsCommand() {
|
|
|
87510
87768
|
cmd.addCommand(createPositionsClaimCommand());
|
|
87511
87769
|
cmd.addCommand(createPositionsClaimRewardsCommand());
|
|
87512
87770
|
cmd.addCommand(createPositionsClaimBonusCommand());
|
|
87771
|
+
cmd.addCommand(createSubmitRewardsCommand());
|
|
87513
87772
|
cmd.addCommand(createPositionsAnalyzeCommand());
|
|
87514
87773
|
cmd.addCommand(createTopPositionsCommand());
|
|
87515
87774
|
cmd.addCommand(createCopyPositionCommand());
|