Skip to content

feat: add channels add/list/fund subcommands - #224

Merged
AbdulmalikAlayande merged 2 commits into
TegoLabs:mainfrom
mrteeednut007-dotcom:feat/channels-command
Jun 26, 2026
Merged

AbdulmalikAlayande merged 2 commits into
TegoLabs:mainfrom
mrteeednut007-dotcom:feat/channels-command

Conversation

@mrteeednut007-dotcom

Copy link
Copy Markdown
Contributor

feat: add channels subcommands — add, list, fund

Adds a sorokeep channels command group for managing channel accounts used for fee bumping and
transaction parallelism.

Subcommands:

  • channels add --key [--label] [--network] — registers a Stellar public key as a
    channel account
  • channels list [--network] — lists all registered channel accounts with funded status
  • channels fund --master-key [--amount] [--network] — sends XLM from a master
    wallet to all registered channel accounts in a single transaction

Implementation:

  • New channel_accounts SQLite table (with live migration for existing databases)
  • sendPayments() on StellarRpcClient — builds a standard transaction with one PaymentOp per
    destination
  • Core logic in src/core/channels.ts, CLI in src/commands/channels.ts
  • 8 tests covering happy paths, duplicate key rejection, empty account guard, and error
    propagation

Testing:

All 8 new tests pass. Full suite: 235 tests across 14 files, 0 failures.

closes #196

@coderabbitai

coderabbitai Bot commented Jun 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@AbdulmalikAlayande, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 15 minutes and 7 seconds. Learn how PR review limits work.

To continue reviewing without waiting, enable usage-based billing in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9366e911-9e2f-483e-8243-cbaf8f46fb32

📥 Commits

Reviewing files that changed from the base of the PR and between 7efd589 and 6056d0b.

📒 Files selected for processing (1)
  • package.json
📝 Walkthrough

Walkthrough

Adds a channels CLI command group with add, list, and fund subcommands. Introduces a channel_accounts SQLite table (schema + live migration), repository CRUD functions, a sendPayments method on StellarRpcClient for multi-destination XLM payments, core orchestration logic, CLI wiring, and Vitest tests.

Changes

Channel Account Management

Layer / File(s) Summary
channel_accounts schema and repository
src/db/schema.sql, src/db/database.ts, src/db/repositories.ts
Defines the channel_accounts table (unique public_key, network, funded flag, created_at) in both the SQL schema and as a CREATE TABLE IF NOT EXISTS live migration. Adds the ChannelAccount interface and insertChannelAccount, getChannelAccounts, markChannelFunded repository exports.
StellarRpcClient.sendPayments
src/rpc/client.ts
Adds the sendPayments method that builds a single transaction with one payment operation per destination, signs, submits, and polls for confirmation. Short-circuits to success on empty destination list.
Core channel operations
src/core/channels.ts
Introduces FundChannelsResult and implements addChannel, listChannels, and fundChannels. fundChannels fetches accounts by network, dispatches payments via StellarRpcClient, marks accounts funded in the DB on success, and returns a result with funded count, tx hash, and errors.
channels CLI command
src/commands/channels.ts, src/index.ts
Registers channels add/list/fund subcommands via registerChannelsCommand. Each subcommand validates state, calls the corresponding core function, and formats output with chalk. Command is wired into the main CLI entry point.
CLI command tests
tests/commands/channels.test.ts
Vitest suite covering add (registration, duplicates), list (output, empty state), and fund (success, errors, no-accounts exit). Mocks fundChannels and getDatabase; spies on console.log, console.error, and process.exit.
package.json updates
package.json
Reformats the files array to multi-line; adds @rolldown/binding-linux-x64-gnu to devDependencies.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as channels fund (CLI)
    participant Core as fundChannels (core)
    participant DB as SQLite (repositories)
    participant RPC as StellarRpcClient

    User->>CLI: sorokeep channels fund --master-key SK... --amount 10
    CLI->>DB: getChannelAccounts(network)
    DB-->>CLI: ChannelAccount[]
    CLI->>Core: fundChannels(db, masterKey, amount, network, rpcUrl)
    Core->>DB: getChannelAccounts(network)
    DB-->>Core: ChannelAccount[]
    Core->>RPC: sendPayments(destinations, masterKey)
    RPC->>RPC: build multi-op XLM transaction
    RPC-->>Core: SubmitTransactionResult
    Core->>DB: markChannelFunded(publicKey) per account
    Core-->>CLI: FundChannelsResult { funded, txHash, errors }
    CLI->>User: print success / error output
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • AbdulmalikAlayande/sorokeep#7: Both PRs modify src/db/database.ts's getDatabase() migration logic — that PR adjusts DB path/directory setup while this one adds the channel_accounts table migration.

Poem

🐇 Hop, hop, here's a channel for you,
A public key added, the funding comes through!
XLM payments sent in one tidy batch,
The SQLite rows marked — no value to scratch.
channels add, list, fund — the trio is here,
This bunny ships features with flourish and cheer! 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning package.json adds a new devDependency and formatting changes that are not part of the channel-account management scope. Remove the unrelated dependency change, or document why it is needed for the channels feature if it must stay.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title succinctly describes the main change: adding channels add/list/fund subcommands.
Description check ✅ Passed The description matches the implemented channels command group and supporting database/RPC changes.
Linked Issues check ✅ Passed The PR implements the requested add, list, and fund commands, standard payment-based funding, and tests for the required behaviors.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@drips-wave

drips-wave Bot commented Jun 24, 2026

Copy link
Copy Markdown

@mrteeednut007-dotcom Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@gitguardian

gitguardian Bot commented Jun 24, 2026 •

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 2 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
- - Generic High Entropy Secret 7efd589 tests/commands/channels.test.ts View secret
- - Generic High Entropy Secret 617e5cd tests/rpc/client.test.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/commands/channels.ts`:
- Around line 92-103: The channels fund handler in fundChannels() only logs
result.errors and still completes successfully, so a failed run is reported as
success. Update the command flow in src/commands/channels.ts so that when
result.errors.length > 0 you terminate with a non-zero exit status or rethrow
after logging the errors, while preserving the existing success logging for
result.funded and result.txHash when funding actually succeeds.

In `@src/core/channels.ts`:
- Around line 16-23: addChannel currently persists any string as public_key, so
malformed keys can later break fundChannels when it builds a transaction from
all stored accounts. Update addChannel in channels.ts to validate the publicKey
argument in core before calling insertChannelAccount, and reject or throw on
invalid keys so non-CLI callers cannot store unusable channel records.

In `@src/db/repositories.ts`:
- Around line 446-448: `markChannelFunded()` is updating rows by public key
only, so it can mark the wrong network’s channel as funded. Update the
repository method signature to accept `network` and use it in the `UPDATE
channel_accounts` query so the row is matched by both `network` and
`public_key`; then follow through any callers of `markChannelFunded()` to pass
the network value consistently.

In `@src/db/schema.sql`:
- Around line 73-80: The channel account uniqueness is currently global on
public_key, which conflicts with network-scoped accounts. Update the
channel_accounts schema to enforce uniqueness on the pair handled by the account
model, using the channel account table definition in schema.sql and the matching
migration logic in src/db/database.ts. Keep the same uniqueness shape in both
places so the add flow for channels can allow the same public key on different
networks without hitting a SQLite constraint error.

In `@tests/commands/channels.test.ts`:
- Around line 179-203: The failed funding test only checks stderr and is missing
the exit-code contract for `channels fund`; update the `registerChannelsCommand`
/ `program.parseAsync` test to also assert the CLI exits non-zero on
`fundChannels` errors, matching the pattern used in the empty-account guard
test. Keep the existing `"Insufficient balance"` stderr assertion, and add the
same rejected `parseAsync()` or `process.exit` expectation so the failure path
in `fundChannels` is fully covered.
- Line 25: The hardcoded secret in the channels test should be removed because
it is a committed credential. Update the test setup in channels.test.ts around
MASTER_KEY to use a generated disposable test key, a mock fixture, or another
non-sensitive value instead of a real Stellar secret. If this value ever
corresponded to a live account, ensure it is rotated or revoked and that any
helper code or constants referencing MASTER_KEY are updated accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7cc7ece4-38d5-4713-8be4-11630c119755

📥 Commits

Reviewing files that changed from the base of the PR and between c465cc7 and 7efd589.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • package.json
  • src/commands/channels.ts
  • src/core/channels.ts
  • src/db/database.ts
  • src/db/repositories.ts
  • src/db/schema.sql
  • src/index.ts
  • src/rpc/client.ts
  • tests/commands/channels.test.ts
📜 Review details
🧰 Additional context used
🪛 Betterleaks (1.5.0)
tests/commands/channels.test.ts

[high] 25-25: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 54-54: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 77-77: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 99-99: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 GitHub Check: GitGuardian Security Checks
tests/commands/channels.test.ts

[error] 25-25: GitGuardian detected a hardcoded secret: 'Generic High Entropy Secret' (GitGuardian id referenced in report). Detected in commit 7efd589 at tests/commands/channels.test.ts (diff line R25). Remediate by removing/replacing the secret, storing it securely, and revoking/rotating as appropriate.

🪛 OpenGrep (1.23.0)
tests/commands/channels.test.ts

[WARNING] 25-25: Hardcoded AWS access key detected. Use environment variables or a secrets manager instead.

(coderabbit.secrets.aws-access-key)

🔇 Additional comments (1)
package.json (1)

6-11: LGTM!

Also applies to: 49-49

Comment thread src/commands/channels.ts
Comment on lines +92 to +103
if (result.errors.length > 0) {
for (const err of result.errors) {
console.error(chalk.red(`Error: ${err}`));
}
}

if (result.funded > 0) {
console.log(chalk.green(`✔ Funded ${result.funded} channel account(s) successfully.`));
if (result.txHash) {
console.log(` Tx hash: ${chalk.cyan(result.txHash)}`);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Return a failing exit code when funding fails.

When fundChannels() returns errors, this handler only prints them and then exits successfully. That makes a failed sorokeep channels fund run look successful to CI and shell scripts.

Exit non-zero after logging the errors (or rethrow) whenever funding fails.

Suggested fix
             if (result.errors.length > 0) {
                 for (const err of result.errors) {
                     console.error(chalk.red(`Error: ${err}`));
                 }
+                process.exit(1);
             }
 
             if (result.funded > 0) {
                 console.log(chalk.green(`✔ Funded ${result.funded} channel account(s) successfully.`));
                 if (result.txHash) {
📝 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
if (result.errors.length > 0) {
for (const err of result.errors) {
console.error(chalk.red(`Error: ${err}`));
}
}
if (result.funded > 0) {
console.log(chalk.green(`✔ Funded ${result.funded} channel account(s) successfully.`));
if (result.txHash) {
console.log(` Tx hash: ${chalk.cyan(result.txHash)}`);
}
}
if (result.errors.length > 0) {
for (const err of result.errors) {
console.error(chalk.red(`Error: ${err}`));
}
process.exit(1);
}
if (result.funded > 0) {
console.log(chalk.green(`✔ Funded ${result.funded} channel account(s) successfully.`));
if (result.txHash) {
console.log(` Tx hash: ${chalk.cyan(result.txHash)}`);
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/commands/channels.ts` around lines 92 - 103, The channels fund handler in
fundChannels() only logs result.errors and still completes successfully, so a
failed run is reported as success. Update the command flow in
src/commands/channels.ts so that when result.errors.length > 0 you terminate
with a non-zero exit status or rethrow after logging the errors, while
preserving the existing success logging for result.funded and result.txHash when
funding actually succeeds.

Comment thread src/core/channels.ts
Comment on lines +16 to +23
export function addChannel(
db: Database.Database,
publicKey: string,
network: string,
label?: string,
): void {
insertChannelAccount(db, { public_key: publicKey, network, label });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject malformed public keys before persisting them.

addChannel() stores any string as public_key. One bad row here becomes a durable failure for fundChannels(), because the later multi-payment transaction is built from every stored account in that network.

Validate the channel key in core before calling insertChannelAccount() so non-CLI callers cannot persist unusable channel records.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/channels.ts` around lines 16 - 23, addChannel currently persists any
string as public_key, so malformed keys can later break fundChannels when it
builds a transaction from all stored accounts. Update addChannel in channels.ts
to validate the publicKey argument in core before calling insertChannelAccount,
and reject or throw on invalid keys so non-CLI callers cannot store unusable
channel records.

Comment thread src/db/repositories.ts
Comment on lines +446 to +448
export function markChannelFunded(db: Database.Database, publicKey: string): void {
db.prepare("UPDATE channel_accounts SET funded = 1 WHERE public_key = ?").run(publicKey);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Scope funded updates by network.

markChannelFunded() updates every row matching the public key, regardless of network. That breaks the network-scoped contract of this feature: funding a testnet channel would also mark the mainnet row as funded for the same address.

Pass network through this repository method and update on (network, public_key) instead.

Suggested fix
-export function markChannelFunded(db: Database.Database, publicKey: string): void {
-    db.prepare("UPDATE channel_accounts SET funded = 1 WHERE public_key = ?").run(publicKey);
+export function markChannelFunded(db: Database.Database, publicKey: string, network: string): void {
+    db.prepare(
+        "UPDATE channel_accounts SET funded = 1 WHERE public_key = ? AND network = ?"
+    ).run(publicKey, network);
 }
📝 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
export function markChannelFunded(db: Database.Database, publicKey: string): void {
db.prepare("UPDATE channel_accounts SET funded = 1 WHERE public_key = ?").run(publicKey);
}
export function markChannelFunded(db: Database.Database, publicKey: string, network: string): void {
db.prepare(
"UPDATE channel_accounts SET funded = 1 WHERE public_key = ? AND network = ?"
).run(publicKey, network);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/db/repositories.ts` around lines 446 - 448, `markChannelFunded()` is
updating rows by public key only, so it can mark the wrong network’s channel as
funded. Update the repository method signature to accept `network` and use it in
the `UPDATE channel_accounts` query so the row is matched by both `network` and
`public_key`; then follow through any callers of `markChannelFunded()` to pass
the network value consistently.

Comment thread src/db/schema.sql
Comment on lines +73 to +80
CREATE TABLE IF NOT EXISTS channel_accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
public_key TEXT NOT NULL UNIQUE,
label TEXT,
network TEXT NOT NULL DEFAULT 'testnet',
funded BOOLEAN NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make channel uniqueness network-scoped.

public_key TEXT NOT NULL UNIQUE blocks registering the same address on both testnet and mainnet, even though the rest of this feature scopes channel accounts by network. Today that means channels add --network mainnet can bypass the CLI duplicate check and then fail with a raw SQLite constraint error if the same key was already added on testnet.

Use a composite uniqueness constraint on (network, public_key) here, and mirror the same shape in the live migration in src/db/database.ts.

Suggested schema shape
 CREATE TABLE IF NOT EXISTS channel_accounts (
     id INTEGER PRIMARY KEY AUTOINCREMENT,
-    public_key TEXT NOT NULL UNIQUE,
+    public_key TEXT NOT NULL,
     label TEXT,
     network TEXT NOT NULL DEFAULT 'testnet',
     funded BOOLEAN NOT NULL DEFAULT 0,
-    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
+    created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    UNIQUE (network, public_key)
 );
📝 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
CREATE TABLE IF NOT EXISTS channel_accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
public_key TEXT NOT NULL UNIQUE,
label TEXT,
network TEXT NOT NULL DEFAULT 'testnet',
funded BOOLEAN NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS channel_accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
public_key TEXT NOT NULL,
label TEXT,
network TEXT NOT NULL DEFAULT 'testnet',
funded BOOLEAN NOT NULL DEFAULT 0,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (network, public_key)
);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/db/schema.sql` around lines 73 - 80, The channel account uniqueness is
currently global on public_key, which conflicts with network-scoped accounts.
Update the channel_accounts schema to enforce uniqueness on the pair handled by
the account model, using the channel account table definition in schema.sql and
the matching migration logic in src/db/database.ts. Keep the same uniqueness
shape in both places so the add flow for channels can allow the same public key
on different networks without hitting a SQLite constraint error.

});

describe("channels command", () => {
const MASTER_KEY = "SCZANGBA5AKIA5OSBZPZU5KA5BWNNASCTLZ5I3XUGP7ZXFJEFZ4MFLN";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Remove the committed secret key.

This hardcoded Stellar secret is already tripping GitGuardian. Even in tests, checked-in secret seeds need to be treated as compromised. Replace it with a generated disposable test key or a non-sensitive fixture, and revoke/rotate it if it ever backed a real account.

🧰 Tools
🪛 Betterleaks (1.5.0)

[high] 25-25: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 GitHub Check: GitGuardian Security Checks

[error] 25-25: GitGuardian detected a hardcoded secret: 'Generic High Entropy Secret' (GitGuardian id referenced in report). Detected in commit 7efd589 at tests/commands/channels.test.ts (diff line R25). Remediate by removing/replacing the secret, storing it securely, and revoking/rotating as appropriate.

🪛 OpenGrep (1.23.0)

[WARNING] 25-25: Hardcoded AWS access key detected. Use environment variables or a secrets manager instead.

(coderabbit.secrets.aws-access-key)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/commands/channels.test.ts` at line 25, The hardcoded secret in the
channels test should be removed because it is a committed credential. Update the
test setup in channels.test.ts around MASTER_KEY to use a generated disposable
test key, a mock fixture, or another non-sensitive value instead of a real
Stellar secret. If this value ever corresponded to a live account, ensure it is
rotated or revoked and that any helper code or constants referencing MASTER_KEY
are updated accordingly.

Sources: Linters/SAST tools, Pipeline failures

Comment on lines +179 to +203
it("reports errors from fundChannels", async () => {
const { fundChannels } = await import("../../src/core/channels.js");
(fundChannels as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
funded: 0,
txHash: "",
errors: ["Insufficient balance"],
});

// Need at least one account so the guard doesn't block
insertChannelAccount(mockDb, { public_key: "GDQJUTQYK2MQX2VGDR2FYWLIYAQIEGXTQVTFEMGH85FYDNE5VRLJQJN5", network: "testnet" });

const program = new Command();
registerChannelsCommand(program);

await program.parseAsync([
"node", "sorokeep",
"channels", "fund",
"--master-key", MASTER_KEY,
"--amount", "10",
"--network", "testnet",
]);

expect(consoleErrorSpy).toHaveBeenCalledWith(
expect.stringContaining("Insufficient balance")
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the exit-code contract on failed funding.

This case only asserts stderr output. Once the CLI returns a non-zero exit for funding failures, add the same rejected parseAsync() / process.exit expectation used by the empty-account test so the regression stays covered.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/commands/channels.test.ts` around lines 179 - 203, The failed funding
test only checks stderr and is missing the exit-code contract for `channels
fund`; update the `registerChannelsCommand` / `program.parseAsync` test to also
assert the CLI exits non-zero on `fundChannels` errors, matching the pattern
used in the empty-account guard test. Keep the existing `"Insufficient balance"`
stderr assertion, and add the same rejected `parseAsync()` or `process.exit`
expectation so the failure path in `fundChannels` is fully covered.

@AbdulmalikAlayande
AbdulmalikAlayande merged commit 8bc6f58 into TegoLabs:main Jun 26, 2026
1 of 2 checks passed
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.

feat(cli): add channel account management commands

2 participants