Skip to content

Conversation

@marchuk-vlad
Copy link
Contributor

@marchuk-vlad marchuk-vlad commented Jun 18, 2025

Summary by CodeRabbit

  • New Features
    • Added new CLI commands to manage offer versions, including adding and disabling specific versions.
    • Introduced a workflow command to replenish deposits for blockchain orders with flexible options.
  • Dependency Updates
    • Updated package versions for @super-protocol/ctl and @super-protocol/sdk-js.
  • Improvements
    • Enhanced offer version info validation and reading.
    • Improved error handling and user prompts for new commands.
  • Utilities
    • Added a utility for robust number parsing in CLI arguments.

Villain88 and others added 17 commits May 23, 2025 12:12
* update sdk

* sdk-3.11.3
* feat(replenish-deposit): Add replenish workflow cmd

* feat(replenish-deposit): add option --yes

* fix(replenish-deposit): add parser for --minutes option

* fix(replenish-deposit): change minutes logic

---------

Co-authored-by: Petr Evstifeev <7293601+Villain88@users.noreply.github.com>
* feat(offer version): add offer version command

* fix(offer version): change option to requiredOption

* fix(offer version): update code after tests

* fix(update version):  ai review changes

* chore(update version): update log messages

* fix(offer versions): review changes

* fix(offer-version): argument parsing in cmd
…latest

fix(create-order): Use fromBlock toBlock
@coderabbitai
Copy link

coderabbitai bot commented Jun 18, 2025

Walkthrough

This update introduces new CLI commands for managing offer versions and workflow deposit replenishments, adds supporting service modules for reading and validating offer version info, and updates dependency versions. Schema definitions are refined for offer restrictions, and a utility for parsing numbers is added. Existing logic remains unchanged.

Changes

File(s) Change Summary
package.json Bumped @super-protocol/ctl to 0.11.6 and @super-protocol/sdk-js to 3.11.4.
src/commands/offerAddVersion.ts, src/commands/offerDisableVersion.ts Added new commands for adding and disabling offer versions on the blockchain.
src/commands/workflowsReplenishDeposit.ts Introduced workflow command to replenish deposits for blockchain orders.
src/index.ts Registered new CLI commands: offer version add/disable and workflows replenish-deposit; integrated new utilities.
src/services/createOrder.ts Updated order retrieval to use latest block info for more precise event querying.
src/services/readOfferVersionInfo.ts Added module to read and validate offer version info files using schema validation.
src/services/readValueOfferInfo.ts Modified offer restrictions schema: changed offers to array of {id, version} objects; removed versions array.
src/utils.ts Added parseNumber utility for validated number parsing in CLI arguments.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant BlockchainService
    participant FileService

    User->>CLI: Run 'offer version add' with params
    CLI->>FileService: Read and validate version info file
    FileService-->>CLI: Return validated version info
    CLI->>BlockchainService: Add new offer version with info
    BlockchainService-->>CLI: Confirm addition
    CLI-->>User: Print success or error message
Loading
sequenceDiagram
    participant User
    participant CLI
    participant BlockchainService

    User->>CLI: Run 'workflows replenish-deposit' with params
    CLI->>BlockchainService: Fetch order status
    BlockchainService-->>CLI: Return order status
    CLI->>User: Prompt for confirmation (unless silent)
    User-->>CLI: Confirm (if prompted)
    CLI->>BlockchainService: Replenish deposit
    BlockchainService-->>CLI: Confirm replenishment
    CLI-->>User: Print result
Loading

Poem

In the warren of code, new features appear,
Offers gain versions, deposits draw near.
With numbers parsed safely, and schemas refined,
The blockchain hops forward—no rabbit left behind!
🐇✨

CLI commands multiply,
As dependencies hop high!

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-18T15_16_22_607Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@marchuk-vlad marchuk-vlad merged commit 558ddf6 into main Jun 18, 2025
4 of 5 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (8)
src/utils.ts (1)

203-207: Be stricter when validating CLI numeric arguments

Number('') returns 0 and Number('Infinity') returns Infinity, both of which silently pass the current check but are very unlikely to be valid values for things like a version or timeout. Consider rejecting empty / whitespace‐only strings and anything that is not a finite decimal number.

 export const parseNumber = (val: string): number => {
-  const parsed = Number(val);
-  if (Number.isNaN(parsed)) throw new InvalidArgumentError('Not a number.');
-  return parsed;
+  const trimmed = val.trim();
+  if (!/^-?\d+(\.\d+)?$/.test(trimmed)) {
+    throw new InvalidArgumentError('Expected a decimal number.');
+  }
+
+  const parsed = Number(trimmed);
+  if (!Number.isFinite(parsed)) {
+    throw new InvalidArgumentError('Number is not finite.');
+  }
+  return parsed;
 };
src/services/readOfferVersionInfo.ts (2)

3-3: Use a relative import without the unnecessary directory hop

The file lives in the same folder as readResourceFile.ts, so ../services/... walks one level up and then immediately back down. Using a direct relative path is clearer and avoids breakage if the folder structure ever changes.

-import { HashValidator } from '../services/readResourceFile';
+import { HashValidator } from './readResourceFile';

16-23: Propagate the validator’s type to avoid an extra cast

If readJsonFile is generic, pass the expected type so the result is strongly typed without an explicit cast:

const offerOption = await readJsonFile<OfferVersionInfo>({
  path: params.path,
  validator: OfferVersionInfoSchema,
});

This catches schema ↔ type mismatches at compile time.

src/services/createOrder.ts (1)

12-22: Typo in variable name and minor ordering concern

  1. workflowCreationBLock has a capital “L” in the middle – reads oddly and may trip linters.
  2. Capturing the last block before Orders.createOrder means the order itself will be created in a later block, but you start scanning from the earlier height anyway. That’s fine, just making sure it was intentional.
- const workflowCreationBLock = await BlockchainConnector.getInstance().getLastBlockInfo();
+ const workflowCreationBlock = await BlockchainConnector.getInstance().getLastBlockInfo();
 ...
-      workflowCreationBLock.index,
+      workflowCreationBlock.index,
src/commands/offerAddVersion.ts (2)

18-21: Returned actionAddress is computed but then discarded

initBlockchainConnector resolves with the address derived from actionAccountKey, yet the value is neither used nor verified.
If addValueOfferVersion needs the address, pass it; otherwise call the connector for its side-effects once and rename to make this explicit.


23-28: Ambiguous field name action in service call

You pass the private key via the property action, whereas the rest of the codebase consistently uses actionAccountKey.
Keeping the same naming avoids confusion and unintended structural typing mistakes.

src/index.ts (2)

479-512: Option parsing duplicates logic & bypasses parseNumber

--minutes uses a custom argParser(parseInt) despite having the new parseNumber helper. This duplicates logic and bypasses central validation (e.g., negative values).
Reuse parseNumber here for consistency.

-      ).argParser((val) => parseInt(val) || 0),
+      ).argParser(parseNumber),

1460-1478: Duplicate root commands: offer vs offers

The CLI now features both offers … and single offer version … command trees. This confuses users and breaks tab-completion. Prefer nesting version commands under the existing offers root (e.g., offers version add).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67de679 and 6e88efc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • package.json (2 hunks)
  • src/commands/offerAddVersion.ts (1 hunks)
  • src/commands/offerDisableVersion.ts (1 hunks)
  • src/commands/workflowsReplenishDeposit.ts (1 hunks)
  • src/index.ts (5 hunks)
  • src/services/createOrder.ts (2 hunks)
  • src/services/readOfferVersionInfo.ts (1 hunks)
  • src/services/readValueOfferInfo.ts (1 hunks)
  • src/utils.ts (2 hunks)
🔇 Additional comments (4)
src/utils.ts (1)

3-3: Ensure Commander version ≥ 8.0 is locked in

InvalidArgumentError ships with Commander 8+. package.json currently has "commander": "^8.3.0", which is fine, but please keep an eye on this if you ever downgrade or pin a lower major version.

package.json (1)

3-3: Version bumps look sane

Bumping @super-protocol/ctl to 0.11.6 aligns the CLI with the new commands. No issues spotted here.

src/services/readValueOfferInfo.ts (1)

19-26: Down-stream code may still expect offers: string[]

offers is now an array of { id, version }. Any existing logic that did offers.includes(...), treated items as strings, or relied on the old schema will break at runtime.

Please grep the project (including tests) for:

rg --context 2 '\.offers'

and update usages accordingly.

src/index.ts (1)

502-509: Potential undefined minutes / sppi pass-through

WorkflowReplenishDepositParams.minutes is declared number, but can be undefined when only --sppi is supplied, violating the type contract and risking runtime NaN checks inside the service.
Mark the fields optional or ensure defaults before passing.

Comment on lines +5 to +10
export type OffersDisableVersionParams = {
blockchainConfig: BlockchainConfig;
actionAccountKey: string;
id: string;
ver: number;
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Input contract lacks basic sanity checks

id might be an empty string and ver could be <1; this will go straight to the chain and revert.
Add lightweight guards before the blockchain call.

🤖 Prompt for AI Agents
In src/commands/offerDisableVersion.ts between lines 5 and 10, the
OffersDisableVersionParams type lacks validation for the id and ver fields. Add
checks before the blockchain call to ensure id is not an empty string and ver is
at least 1. If these conditions are not met, throw an error or return early to
prevent sending invalid data to the blockchain and causing a revert.

Comment on lines +22 to +24
} catch (error: any) {
Printer.print('Remove offer version failed with error: ' + error?.message);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Swallowed error obstructs CLI exit status

The catch block only logs the error. The CLI that invokes this command will interpret a resolved promise as success, masking failures (e.g., CI/CD scripts will think the version was removed).
After logging, re-throw the error or process.exit(1) so the caller can react.

-  } catch (error: any) {
-    Printer.print('Remove offer version failed with error: ' + error?.message);
+  } catch (error: unknown) {
+    Printer.print(`Remove offer version failed: ${(error as Error).message}`);
+    throw error;        // let the upper layer decide how to handle/exit
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error: any) {
Printer.print('Remove offer version failed with error: ' + error?.message);
}
} catch (error: unknown) {
Printer.print(`Remove offer version failed: ${(error as Error).message}`);
throw error; // let the upper layer decide how to handle/exit
}
🤖 Prompt for AI Agents
In src/commands/offerDisableVersion.ts around lines 22 to 24, the catch block
logs the error but does not propagate it, causing the CLI to treat failures as
successes. To fix this, after logging the error message, either re-throw the
caught error or call process.exit(1) to ensure the CLI exits with a failure
status and the caller can handle the error properly.

Comment on lines +15 to +33
export default async (params: OfferAddVersionParams): Promise<void> => {
try {
Printer.print('Connecting to the blockchain');
await initBlockchainConnector({
blockchainConfig: params.blockchainConfig,
actionAccountKey: params.actionAccountKey,
});
const versionInfo = await readOfferVersionInfo({ path: params.path });
const newVersion = await addValueOfferVersion({
action: params.actionAccountKey,
version: params.ver,
versionInfo,
offerId: params.id,
});
Printer.print(`Version ${newVersion} added successfully`);
} catch (error: any) {
Printer.print('Version add failed with error: ' + error?.message);
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing propagation of failures

Same as in offerDisableVersion.ts: the error is logged but not re-thrown, so upstream code can’t tell the command failed.

🤖 Prompt for AI Agents
In src/commands/offerAddVersion.ts around lines 15 to 33, the catch block logs
the error but does not re-throw it, preventing upstream code from detecting the
failure. Modify the catch block to re-throw the caught error after logging it,
ensuring that the failure propagates properly to calling functions.

Comment on lines +70 to +72
} catch (error: any) {
Printer.print(`Order ${params.orderId} was not replenished: ${error?.message}`);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Error object typed as any and swallowed

Re-throw after logging (see comments in other files) so the CLI command reflects failure status and exit code.

🤖 Prompt for AI Agents
In src/commands/workflowsReplenishDeposit.ts around lines 70 to 72, the catch
block types the error as any and only logs it without re-throwing. Modify the
catch block to re-throw the caught error after logging the message so that the
CLI command properly reflects the failure status and exit code.

Comment on lines +60 to +64
const confirmed =
params.yes ||
(await isActionConfirmed(
`Deposit will be replenished by ${weiToEther(tokenAmount)} SPPI. Order time is extended by ${minutes} minutes.`,
));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Dual-input ambiguity

If the user provides both --minutes and --sppi, the first if (params.minutes) branch silently wins. Make this mutually exclusive and throw if both are set.

🤖 Prompt for AI Agents
In src/commands/workflowsReplenishDeposit.ts around lines 60 to 64, the code
allows both --minutes and --sppi parameters to be set simultaneously, but only
processes the --minutes branch silently. To fix this, add a check before this
logic to detect if both params.minutes and params.sppi are set, and if so, throw
an error indicating that these options are mutually exclusive. This prevents
ambiguity by enforcing that only one of these inputs can be provided at a time.

Comment on lines +50 to +58
if (params.minutes) {
tokenAmount = (BigInt(amountPerHour) * BigInt(params.minutes)) / 60n;
minutes = params.minutes;
} else if (params.sppi) {
tokenAmount = etherToWei(params.sppi).toBigInt();
minutes = Number((tokenAmount * 60n) / BigInt(amountPerHour));
} else {
throw new Error('To complete command please define one of arguments --sppi or --minutes');
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Calculation loses precision for non-divisible minute values

tokenAmount = amountPerHour * minutes / 60 truncates towards zero (BigInt division), potentially under-funding the order.
Example: amountPerHour = 100, minutes = 59tokenAmount = 98 instead of 98.333….
Consider ceiling division or informing the user about the rounding strategy.

🤖 Prompt for AI Agents
In src/commands/workflowsReplenishDeposit.ts around lines 50 to 58, the
calculation of tokenAmount uses integer division with BigInt, which truncates
and loses precision for non-divisible minute values. To fix this, implement a
ceiling division approach to round up the result instead of truncating, ensuring
the tokenAmount does not under-fund the order. Adjust the formula to calculate
tokenAmount as (amountPerHour * minutes + 59) / 60 or an equivalent method to
achieve ceiling division with BigInt.

Comment on lines +1438 to +1458
offerVersionCommand
.command('add')
.description('Add new version of offer')
.requiredOption('--offer <id>', 'Offer id')
.requiredOption('--path <path>', 'Path to offer version info file')
.option('--ver <version>', 'Version number to add', parseNumber)
.action(async (options: { offer: string; path: string; ver: number; config: string }) => {
const configLoader = new ConfigLoader(options.config);
const blockchain = configLoader.loadSection('blockchain');
const blockchainConfig = {
contractAddress: blockchain.smartContractAddress,
blockchainUrl: blockchain.rpcUrl,
};
await offerAddVersion({
actionAccountKey: blockchain.accountPrivateKey,
blockchainConfig,
id: options.offer,
ver: options.ver,
path: options.path,
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

ver is optional in CLI but required in service type

When --ver is omitted, options.ver is undefined, yet OfferAddVersionParams.ver is non-optional. TypeScript will compile due to any, but at runtime the service receives undefined and may fail on-chain.

Either:

  1. Make the CLI option .requiredOption, or
  2. Change the param to ver?: number and let the service auto-increment.
🤖 Prompt for AI Agents
In src/index.ts around lines 1438 to 1458, the CLI option --ver is currently
optional but the service expects a non-optional version number, causing runtime
issues if omitted. To fix this, either change the CLI option to
.requiredOption('--ver <version>', ...) to enforce providing a version, or
update the service parameter type to make ver optional (ver?: number) and
implement logic to auto-increment the version when it is not provided. Choose
one approach and update the code accordingly to ensure ver is always valid when
passed to the service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants