Skip to content

Comments

feat(utils): add preimage and payment hash helper#524

Open
naveenkumar29052006 wants to merge 4 commits intogetAlby:masterfrom
naveenkumar29052006:feature/new-function
Open

feat(utils): add preimage and payment hash helper#524
naveenkumar29052006 wants to merge 4 commits intogetAlby:masterfrom
naveenkumar29052006:feature/new-function

Conversation

@naveenkumar29052006
Copy link

@naveenkumar29052006 naveenkumar29052006 commented Jan 23, 2026

This PR adds a small utility helper to generate a random 32-byte preimage and its corresponding SHA-256 payment hash.

That fixes issue Fixes #523

The goal is to avoid duplicating Web Crypto and hex-encoding logic in multiple places (e.g. hold invoice flows and examples) and keep the implementation consistent and easy to reuse.

No behavior changes — this is a pure DX and maintainability improvement.
Screenshot 2026-01-23 at 10 05 07 PM

Summary by CodeRabbit

  • Refactor
    • Consolidated cryptographic preimage and payment-hash generation into a shared utility; hold-invoice and payment flows behave the same for users.
  • Bug Fixes / Improvements
    • Stronger validation for connection URLs with clearer errors when required fields (relay or secret) are missing.
  • Tests
    • Added validation tests covering missing relay and missing secret scenarios.

@coderabbitai
Copy link

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

Extracts preimage/payment-hash generation into a new async utility in src/utils.ts, updates the hold-invoice example to use it, adds WalletConnect URL validation and related tests in src/nwc, tweaks VSCode settings, and applies a small manifest change to package.json.

Changes

Cohort / File(s) Summary
Utility
src/utils.ts
Added async function generatePreimageAndPaymentHash() (returns { preimage, paymentHash }), converted toHexString to a local const and re-exported both via an export block.
Example update
examples/nwc/client/hold-invoice.ts
Replaced inline preimage/payment-hash generation and toHexString helper with imported generatePreimageAndPaymentHash; invoice flow otherwise unchanged.
NWC client + tests
src/nwc/NWCClient.ts, src/nwc/NWCClient.test.ts
Added static validateWalletConnectUrl(options: NWCOptions, requireSecret = false) to enforce relay and secret requirements; parse flow now calls the validator. Added tests for missing relay and missing secret scenarios.
Editor config
.vscode/settings.json
Added a TypeScript-specific formatter override ([typescript] block) while preserving existing settings.
Manifest
package.json
Minor manifest edits (+6/-7 lines).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled bytes beneath the moonlit stash,

Pulled hashes neat from one tidy cache,
No scattered helpers in burrows deep,
A single hop, and the code can sleep,
🥕 Hooray—my repository's stash!

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes several out-of-scope changes: new validation logic in NWCClient.validateWalletConnectUrl, test cases for URL validation, and a VSCode settings configuration update that are unrelated to the primary objective of adding the preimage/payment hash utility. Extract the NWCClient validation logic, related tests, and VSCode settings changes into separate PRs focused on their respective objectives to keep this PR focused solely on the utility helper.
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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding a reusable utility helper for generating preimage and payment hash, which aligns with the primary objective of the changeset.
Linked Issues check ✅ Passed The PR successfully implements the requirement from issue #523: a new generatePreimageAndPaymentHash utility function that encapsulates the previously duplicated crypto logic for generating random preimage bytes, computing SHA-256 hash, and returning both as hex strings.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

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: 1

🤖 Fix all issues with AI agents
In `@src/utils.ts`:
- Around line 5-13: Add an explicit return type to
generatePreimageAndPaymentHash (async function generatePreimageAndPaymentHash():
Promise<{ preimage: string; paymentHash: string }>) and make the function
Node-compatible by importing Node's crypto module (import crypto from 'crypto')
and switching from browser APIs to Node equivalents: use crypto.randomBytes(32)
for the preimage bytes and
crypto.createHash('sha256').update(preimageBytes).digest() for the payment hash,
then convert both byte arrays to hex via the existing toHexString helper.

@naveenkumar29052006
Copy link
Author

@rolznz sir could u plz check here

@rolznz
Copy link
Contributor

rolznz commented Jan 25, 2026

@naveenkumar29052006 looks good, thanks! can you update the PR description to reference the issue (Fixes #..)

@naveenkumar29052006
Copy link
Author

@rolznz Done Sir

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: 1

🤖 Fix all issues with AI agents
In @.vscode/settings.json:
- Around line 5-7: Remove the TypeScript-specific formatter override that sets
"editor.defaultFormatter": "vscode.typescript-language-features" under the
"[typescript]" VSCode settings so TypeScript files use the project's canonical
formatter (e.g., Prettier) and avoid inconsistent formatting; update or delete
the "[typescript]" block in .vscode/settings.json so it no longer enforces that
formatter.
🧹 Nitpick comments (3)
src/nwc/NWCClient.test.ts (1)

54-71: Tests look good; consider asserting specific error messages.

The new validation tests correctly cover the two error scenarios. For improved test robustness, consider using toThrow(/expected message pattern/) to verify the exact error is thrown, preventing false positives if a different error occurs.

   test("throws when no relay is provided", () => {
     expect(() =>
       NWCClient.parseWalletConnectUrl(
         "nostr+walletconnect://abc123",
       ),
-    ).toThrow();
+    ).toThrow(/no relay/i);
   });

   test("throws when secret is required but missing", () => {
     expect(() =>
       new NWCClient({
         nostrWalletConnectUrl:
           "nostr+walletconnect://abc123?relay=wss://relay.example.com",
       }),
-    ).toThrow();
+    ).toThrow(/missing secret/i);
   });
src/nwc/NWCClient.ts (2)

141-142: Good integration; note that existing relay check is now unreachable.

The validation call is correctly placed. However, the check on lines 125-127 is now effectively dead code since:

  1. url.searchParams.getAll("relay") returns an empty array (not null/undefined) when no relay params exist
  2. validateWalletConnectUrl on line 141 throws for empty relayUrls before returning

Consider removing lines 125-127 to avoid confusion.


147-154: Double validation is redundant.

parseWalletConnectUrl (line 147-149) already calls validateWalletConnectUrl(options) internally before returning. Line 150 then calls validateWalletConnectUrl(parsed, true) again, re-running all the same checks plus the secret requirement.

Consider either:

  1. Adding an optional requireSecret parameter to parseWalletConnectUrl, or
  2. Having parseWalletConnectUrl skip validation and let callers validate as needed
Option 1: Add parameter to parseWalletConnectUrl
-  static parseWalletConnectUrl(walletConnectUrl: string): NWCOptions {
+  static parseWalletConnectUrl(walletConnectUrl: string, requireSecret = false): NWCOptions {
     // ... parsing logic ...
-    NWCClient.validateWalletConnectUrl(options);
+    NWCClient.validateWalletConnectUrl(options, requireSecret);
     return options;
   }

Then in the constructor:

     if (options && options.nostrWalletConnectUrl) {
       const parsed = NWCClient.parseWalletConnectUrl(
         options.nostrWalletConnectUrl,
+        true, // requireSecret
       );
-      NWCClient.validateWalletConnectUrl(parsed, true);
       options = {

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.

Add utility function for generating preimage + payment hash for use with hold invoices

2 participants