@byreal-io/byreal-cli-realclaw 0.3.2 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +2 -1
  2. package/dist/index.cjs +210 -14
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -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 your CLMM positions |
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.2" : void 0;
3036
+ INJECTED_VERSION = true ? "0.3.3" : 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
  };
@@ -82846,6 +82847,19 @@ async function encodeReward(params) {
82846
82847
  }
82847
82848
  return { ok: true, value: data };
82848
82849
  }
82850
+ async function submitRewardOrder(params) {
82851
+ const result = await apiClient.post(API_ENDPOINTS.REWARD_ORDER, {
82852
+ orderCode: params.orderCode,
82853
+ walletAddress: params.walletAddress,
82854
+ signedTxPayload: params.signedTxPayload
82855
+ });
82856
+ if (!result.ok) return result;
82857
+ const data = result.value.result?.data;
82858
+ if (!data) {
82859
+ return { ok: true, value: { orderCode: "", txList: [], claimTokenList: [] } };
82860
+ }
82861
+ return { ok: true, value: data };
82862
+ }
82849
82863
  var api = {
82850
82864
  listPools,
82851
82865
  getPoolInfo,
@@ -82860,7 +82874,8 @@ var api = {
82860
82874
  getUnclaimedData,
82861
82875
  getEpochBonus,
82862
82876
  getProviderOverview,
82863
- encodeReward
82877
+ encodeReward,
82878
+ submitRewardOrder
82864
82879
  };
82865
82880
 
82866
82881
  // src/cli/commands/pools.ts
@@ -83555,6 +83570,25 @@ function outputError(error, format) {
83555
83570
  outputErrorTable(error);
83556
83571
  }
83557
83572
  }
83573
+ function outputRewardOrderResult(result) {
83574
+ console.log(source_default.green.bold("\nRewards Claimed\n"));
83575
+ if (result.claimTokenList.length > 0) {
83576
+ console.log(source_default.white.bold(" Claimed Tokens:"));
83577
+ for (const token of result.claimTokenList) {
83578
+ console.log(source_default.gray(` ${token.tokenAmount} ${token.tokenSymbol} (${token.tokenAddress})`));
83579
+ }
83580
+ console.log();
83581
+ }
83582
+ if (result.txList.length > 0) {
83583
+ console.log(source_default.white.bold(" Transactions:"));
83584
+ for (const tx of result.txList) {
83585
+ const statusLabel = tx.status === 1 ? source_default.green("Success") : tx.status === 2 ? source_default.red("Failed") : source_default.yellow("Sent");
83586
+ console.log(source_default.gray(` ${tx.txSignature} ${statusLabel}`));
83587
+ console.log(source_default.blue(` https://solscan.io/tx/${tx.txSignature}`));
83588
+ }
83589
+ console.log();
83590
+ }
83591
+ }
83558
83592
 
83559
83593
  // src/cli/commands/pools.ts
83560
83594
  async function listPools2(options, globalOptions) {
@@ -84072,7 +84106,7 @@ byreal-cli catalog show dex.pool.list
84072
84106
  | dex.token.list | Query tokens with search |
84073
84107
  | dex.overview.global | Global statistics |
84074
84108
  | dex.swap.execute | Preview or execute a token swap |
84075
- | dex.position.list | List user's CLMM positions |
84109
+ | dex.position.list | List positions for your wallet or any wallet via --user |
84076
84110
  | dex.position.analyze | Analyze existing position |
84077
84111
  | dex.position.open | Open a new CLMM position |
84078
84112
  | dex.position.increase | Add liquidity to an existing position |
@@ -84354,12 +84388,13 @@ byreal-cli swap execute --input-mint So11111111111111111111111111111111111111112
84354
84388
  \`\`\`
84355
84389
 
84356
84390
  ### positions list
84357
- List user's CLMM positions.
84391
+ 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
84392
 
84359
84393
  \`\`\`bash
84360
84394
  byreal-cli positions list [options]
84361
84395
 
84362
84396
  Options:
84397
+ --user <address> Query positions for a specific wallet address (read-only)
84363
84398
  --page <n> Page number (default: 1)
84364
84399
  --page-size <n> Page size (default: 20)
84365
84400
  --sort-field <field> Sort field
@@ -84368,6 +84403,18 @@ Options:
84368
84403
  --status <status> Filter by status: 0=closed, 1=active
84369
84404
  \`\`\`
84370
84405
 
84406
+ Examples:
84407
+ \`\`\`bash
84408
+ # List your own positions
84409
+ byreal-cli positions list --wallet-address <your-addr> -o json
84410
+
84411
+ # Query another user's positions (for LP copy trading research)
84412
+ byreal-cli positions list --user <target-wallet> -o json
84413
+
84414
+ # Query another user's positions in a specific pool
84415
+ byreal-cli positions list --user <target-wallet> --pool <pool-address> -o json
84416
+ \`\`\`
84417
+
84371
84418
  ### positions open
84372
84419
  Open a new CLMM position. Supports two modes: specify token amount (--amount) or USD investment (--amount-usd).
84373
84420
 
@@ -84502,6 +84549,9 @@ Options:
84502
84549
  - **Incentive rewards** \u2192 \`positions claim-rewards\` (this command)
84503
84550
  - **Copy bonus** \u2192 \`positions claim-bonus\` (see below)
84504
84551
 
84552
+ **IMPORTANT \u2014 claim-rewards is a multi-step flow:**
84553
+ 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.
84554
+
84505
84555
  ### positions claim-bonus
84506
84556
  Claim CopyFarmer bonus rewards earned from copying other users' positions. Bonuses accrue in epochs and become claimable in time windows.
84507
84557
 
@@ -84517,6 +84567,24 @@ Options:
84517
84567
  - **Pending**: Settlement period, not yet claimable
84518
84568
  - **Claimable**: Ready to claim within the time window
84519
84569
 
84570
+ **IMPORTANT \u2014 claim-bonus is a multi-step flow** (same as claim-rewards): After signing, call \`positions submit-rewards\` to complete the claim.
84571
+
84572
+ ### positions submit-rewards
84573
+ 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.
84574
+
84575
+ \`\`\`bash
84576
+ byreal-cli positions submit-rewards [options]
84577
+
84578
+ Options:
84579
+ --order-code <code> Order code from claim-rewards or claim-bonus output (required)
84580
+ --signed-payloads <json> JSON array of signed transactions (required)
84581
+ \`\`\`
84582
+
84583
+ The \`--signed-payloads\` format:
84584
+ \`\`\`json
84585
+ [{"txCode":"<from output>","poolAddress":"<from output>","signedTx":"<base64 signed tx>"}]
84586
+ \`\`\`
84587
+
84520
84588
  ### positions top-positions
84521
84589
  Query top positions in a pool. Use this to discover high-performing positions that can be copied.
84522
84590
  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.
@@ -84693,6 +84761,43 @@ When user asks vague questions like "\u6709\u4EC0\u4E48\u4ED3\u4F4D\u53EF\u4EE5
84693
84761
  - 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
84762
  - If user's balance is low (<$20), suggest starting with a single position to minimize gas cost
84695
84763
  - If all positions in a pool are out-of-range, skip that pool and explain why
84764
+ - To inspect a specific LP's full portfolio: \`byreal-cli positions list --user <wallet-address> -o json\`
84765
+
84766
+ ## Workflow: Claim Rewards / Bonus (Multi-Step)
84767
+
84768
+ Claiming incentive rewards (\`claim-rewards\`) and CopyFarmer bonus (\`claim-bonus\`) requires a **3-step flow** because the backend co-signs and broadcasts these transactions:
84769
+
84770
+ **Step 1 \u2014 Preview** (optional but recommended):
84771
+ \`\`\`bash
84772
+ byreal-cli positions claim-rewards --dry-run --wallet-address <addr> -o json
84773
+ \`\`\`
84774
+
84775
+ **Step 2 \u2014 Generate unsigned transactions**:
84776
+ \`\`\`bash
84777
+ byreal-cli positions claim-rewards --wallet-address <addr> -o json
84778
+ \`\`\`
84779
+ Output:
84780
+ \`\`\`json
84781
+ {
84782
+ "orderCode": "ORD_xxx",
84783
+ "unsignedTransactions": [
84784
+ { "poolAddress": "...", "txPayload": "<base64>", "txCode": "TX_xxx", "tokens": [...] }
84785
+ ]
84786
+ }
84787
+ \`\`\`
84788
+
84789
+ **Step 3 \u2014 Sign each \`txPayload\` with the user's wallet**, then submit:
84790
+ \`\`\`bash
84791
+ byreal-cli positions submit-rewards \\
84792
+ --order-code "ORD_xxx" \\
84793
+ --signed-payloads '[{"txCode":"TX_xxx","poolAddress":"...","signedTx":"<base64 signed>"}]' \\
84794
+ --wallet-address <addr> -o json
84795
+ \`\`\`
84796
+ The backend broadcasts the signed transactions on-chain and returns tx signatures + status.
84797
+
84798
+ **For claim-bonus**: Same flow \u2014 replace \`claim-rewards\` with \`claim-bonus\` in Step 1-2; Step 3 is identical (\`submit-rewards\`).
84799
+
84800
+ **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
84801
 
84697
84802
  ## Output Format
84698
84803
 
@@ -84945,11 +85050,12 @@ var CAPABILITIES = [
84945
85050
  {
84946
85051
  id: "dex.position.list",
84947
85052
  name: "List Positions",
84948
- description: "List user CLMM positions with filtering and sorting. Requires --wallet-address global option.",
85053
+ description: "List CLMM positions for your wallet or any wallet address. Use --user to query another wallet (read-only, no --wallet-address needed).",
84949
85054
  category: "query",
84950
- auth_required: true,
84951
- command: "byreal-cli positions list --wallet-address <address>",
85055
+ auth_required: false,
85056
+ command: "byreal-cli positions list",
84952
85057
  params: [
85058
+ { name: "user", type: "string", required: false, description: "Query positions for a specific wallet address (read-only)" },
84953
85059
  { name: "page", type: "integer", required: false, description: "Page number", default: "1" },
84954
85060
  { name: "page-size", type: "integer", required: false, description: "Page size", default: "20" },
84955
85061
  { name: "sort-field", type: "string", required: false, description: "Sort field" },
@@ -85067,6 +85173,18 @@ var CAPABILITIES = [
85067
85173
  { name: "dry-run", type: "boolean", required: false, description: "Preview claimable bonus without claiming" }
85068
85174
  ]
85069
85175
  },
85176
+ {
85177
+ id: "dex.position.submitRewards",
85178
+ name: "Submit Signed Rewards",
85179
+ 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.",
85180
+ category: "execute",
85181
+ auth_required: true,
85182
+ command: "byreal-cli positions submit-rewards --wallet-address <address>",
85183
+ params: [
85184
+ { name: "order-code", type: "string", required: true, description: "Order code from claim-rewards or claim-bonus output" },
85185
+ { name: "signed-payloads", type: "string", required: true, description: 'JSON array of signed transactions: [{"txCode":"...","poolAddress":"...","signedTx":"<base64>"}]' }
85186
+ ]
85187
+ },
85070
85188
  {
85071
85189
  id: "dex.position.topPositions",
85072
85190
  name: "Top Positions",
@@ -85620,25 +85738,31 @@ function serializeTransaction(tx) {
85620
85738
  // src/cli/commands/positions.ts
85621
85739
  init_errors();
85622
85740
  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(
85741
+ 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
85742
  "--status <status>",
85625
85743
  "Filter by status: 0=active, 1=closed (default: 0)"
85626
85744
  ).action(async (options, cmdObj) => {
85627
85745
  const globalOptions = cmdObj.optsWithGlobals();
85628
85746
  const format = globalOptions.output;
85629
85747
  const startTime = Date.now();
85630
- const walletAddress = globalOptions.walletAddress;
85631
- if (!walletAddress) {
85632
- const err2 = missingWalletAddressError();
85748
+ const userAddress = options.user || globalOptions.walletAddress;
85749
+ if (!userAddress) {
85750
+ const errMsg = "Provide --user <address> or global --wallet-address to specify which wallet to query.";
85633
85751
  if (format === "json") {
85634
- outputErrorJson(err2.toJSON());
85752
+ outputErrorJson({ code: "MISSING_ADDRESS", type: "VALIDATION", message: errMsg, retryable: false });
85635
85753
  } else {
85636
- outputErrorTable(err2.toJSON());
85754
+ console.error(source_default.red(`
85755
+ Error: ${errMsg}`));
85637
85756
  }
85638
85757
  process.exit(1);
85639
85758
  }
85759
+ if (options.user && format !== "json") {
85760
+ console.log(source_default.gray(`
85761
+ Positions for: ${options.user}
85762
+ `));
85763
+ }
85640
85764
  const result = await api.listPositions({
85641
- userAddress: walletAddress,
85765
+ userAddress,
85642
85766
  page: parseInt(options.page, 10),
85643
85767
  pageSize: parseInt(options.pageSize, 10),
85644
85768
  sortField: options.sortField,
@@ -87500,6 +87624,77 @@ SDK Error: ${message}`));
87500
87624
  }
87501
87625
  });
87502
87626
  }
87627
+ function createSubmitRewardsCommand() {
87628
+ return new Command("submit-rewards").description(
87629
+ "Submit signed reward/bonus transactions to backend for broadcasting"
87630
+ ).requiredOption(
87631
+ "--order-code <code>",
87632
+ "Order code from claim-rewards or claim-bonus output"
87633
+ ).requiredOption(
87634
+ "--signed-payloads <json>",
87635
+ 'JSON array: [{"txCode":"...","poolAddress":"...","signedTx":"<base64>"}]'
87636
+ ).action(async (options, cmdObj) => {
87637
+ const globalOptions = cmdObj.optsWithGlobals();
87638
+ const format = globalOptions.output;
87639
+ const startTime = Date.now();
87640
+ const walletAddress = globalOptions.walletAddress;
87641
+ if (!walletAddress) {
87642
+ const err2 = missingWalletAddressError();
87643
+ if (format === "json") {
87644
+ outputErrorJson(err2.toJSON());
87645
+ } else {
87646
+ outputErrorTable(err2.toJSON());
87647
+ }
87648
+ process.exit(1);
87649
+ }
87650
+ let signedPayloads;
87651
+ try {
87652
+ signedPayloads = JSON.parse(options.signedPayloads);
87653
+ if (!Array.isArray(signedPayloads) || signedPayloads.length === 0) {
87654
+ throw new Error("must be a non-empty array");
87655
+ }
87656
+ for (const p of signedPayloads) {
87657
+ if (!p.txCode || !p.poolAddress || !p.signedTx) {
87658
+ throw new Error(
87659
+ "each entry must have txCode, poolAddress, signedTx"
87660
+ );
87661
+ }
87662
+ }
87663
+ } catch (e) {
87664
+ const errMsg = `Invalid --signed-payloads: ${e.message}`;
87665
+ if (format === "json") {
87666
+ outputErrorJson({
87667
+ code: "INVALID_PARAMETER",
87668
+ type: "VALIDATION",
87669
+ message: errMsg,
87670
+ retryable: false
87671
+ });
87672
+ } else {
87673
+ console.error(source_default.red(`
87674
+ Error: ${errMsg}`));
87675
+ }
87676
+ process.exit(1);
87677
+ }
87678
+ const orderResult = await api.submitRewardOrder({
87679
+ orderCode: options.orderCode,
87680
+ walletAddress,
87681
+ signedTxPayload: signedPayloads
87682
+ });
87683
+ if (!orderResult.ok) {
87684
+ if (format === "json") {
87685
+ outputErrorJson(orderResult.error);
87686
+ } else {
87687
+ outputErrorTable(orderResult.error);
87688
+ }
87689
+ process.exit(1);
87690
+ }
87691
+ if (format === "json") {
87692
+ outputJson(orderResult.value, startTime);
87693
+ } else {
87694
+ outputRewardOrderResult(orderResult.value);
87695
+ }
87696
+ });
87697
+ }
87503
87698
  function createPositionsCommand() {
87504
87699
  const cmd = new Command("positions").description("Manage CLMM positions");
87505
87700
  cmd.addCommand(createPositionsListCommand());
@@ -87510,6 +87705,7 @@ function createPositionsCommand() {
87510
87705
  cmd.addCommand(createPositionsClaimCommand());
87511
87706
  cmd.addCommand(createPositionsClaimRewardsCommand());
87512
87707
  cmd.addCommand(createPositionsClaimBonusCommand());
87708
+ cmd.addCommand(createSubmitRewardsCommand());
87513
87709
  cmd.addCommand(createPositionsAnalyzeCommand());
87514
87710
  cmd.addCommand(createTopPositionsCommand());
87515
87711
  cmd.addCommand(createCopyPositionCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byreal-io/byreal-cli-realclaw",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "AI-native CLI for Byreal CLMM DEX on Solana",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",