Skip to content

feat(e2e): add NWC contract tests for get_*, hold, multi, and notifications#538

Open
DSanich wants to merge 8 commits intogetAlby:masterfrom
DSanich:feat/nwc-api-contract-e2e-tests
Open

feat(e2e): add NWC contract tests for get_*, hold, multi, and notifications#538
DSanich wants to merge 8 commits intogetAlby:masterfrom
DSanich:feat/nwc-api-contract-e2e-tests

Conversation

@DSanich
Copy link
Copy Markdown
Contributor

@DSanich DSanich commented Mar 26, 2026

Summary

  • Extends the NWC API contract-style e2e suite beyond payment-only flows: get_info, get_budget, faucet get_balance (approximate balance vs exact faucet amount), lookup_invoice (by invoice string and by payment_hash only), list_transactions (outgoing after pay and incoming on the receiver), hold invoices (make / settle / cancel with two-wallet flows and realistic timing), multi_pay_invoice / multi_pay_keysend, and payment_received notifications (subscribe before pay so the relay subscription is active).
  • Adds sign_message e2e: success when allowed, or NOT_IMPLEMENTED / RESTRICTED when the connection lacks scope—without assuming a single error code for “unsupported”.
  • Tightens tests by removing misleading “any failure ⇒ NOT_IMPLEMENTED” patterns where they masked real bugs, and by modeling cancel_hold_invoice correctly (hold in-flight; safe handling of pay_invoice rejection / promise lifecycle after cancel).

Tests

  • End-to-end coverage against the NWC faucet for the flows above, with capability checks, strict success paths where appropriate, and contract-safe outcomes where wallets differ (NOT_IMPLEMENTED, RESTRICTED, payer errors after hold cancel, etc.).

SDK / client changes

  • None in this PR. Reliability fixes for subscribeNotifications (wait until the initial relay subscription is ready) and getWalletServiceInfo (retries when kind 13194 is missing transiently) live in a separate PR: branch fix/nwc-client-relay-subscription. For green CI on notification- and timing-sensitive flows, merge that client PR first (or temporarily base this branch on it), then rebase onto master after it lands.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

Warning

Rate limit exceeded

@DSanich has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 39 minutes and 3 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 39 minutes and 3 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e4082abb-df85-4a36-94e2-4fc7785e671a

📥 Commits

Reviewing files that changed from the base of the PR and between f127441 and 4ab32cc.

📒 Files selected for processing (2)
  • e2e/nwc-cancel-hold-invoice.test.ts
  • e2e/nwc-get-info.test.ts
📝 Walkthrough

Walkthrough

This pull request adds comprehensive end-to-end test coverage for Nostr Wallet Connect (NWC) functionality, including balance retrieval, payment operations (standard and multi-pay), hold invoice lifecycle, message signing, notifications, and transaction listing. It also adjusts an existing faucet test to use a tolerance-based balance assertion.

Changes

Cohort / File(s) Summary
Basic NWC Operations
e2e/nwc-get-info.test.ts, e2e/nwc-get-balance.test.ts, e2e/nwc-get-budget.test.ts, e2e/nwc-sign-message.test.ts
Tests for retrieving wallet metadata, balance, budget, and signing messages; each includes capability gating via NOT_IMPLEMENTED error handling and proper client cleanup.
Hold Invoice Lifecycle
e2e/nwc-make-hold-invoice.test.ts, e2e/nwc-settle-hold-invoice.test.ts, e2e/nwc-cancel-hold-invoice.test.ts
Tests for creating, settling, and canceling hold invoices; includes capability detection via getInfo(), payment initiation during settlement, and strict validation of invoice and preimage correctness.
Multi-Payment Operations
e2e/nwc-multi-pay-invoice.test.ts, e2e/nwc-multi-pay-keysend.test.ts
Tests for paying multiple invoices and executing multi-keysend operations in a single call; includes conditional capability gating and validation of returned preimages.
Notifications & Transaction Queries
e2e/nwc-notifications-payment-received.test.ts, e2e/nwc-list-transactions-after-payment.test.ts, e2e/nwc-lookup-invoice.test.ts
Tests for subscribing to payment notifications, listing incoming/outgoing transactions post-payment, and looking up invoices by payment hash.
Test Infrastructure Updates
e2e/nwc-faucet.test.ts
Modified balance assertion from exact equality to tolerance-based check (≥90% of expected faucet amount) for improved test reliability.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • rolznz

Poem

🐰 A warren of wallets, now tested with care,
Hold invoices settled through methods so fair,
From balance to keysends, we've covered it all,
Each E2E test ensures the NWC won't fall!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding comprehensive NWC contract e2e tests covering get_* methods, hold invoice operations, multi-pay operations, and notifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

@DSanich
Copy link
Copy Markdown
Contributor Author

DSanich commented Mar 26, 2026

@rolznz Hi! I continued my work on e2e tests and prepared this PR. I hope it will be as useful as the previous ones.

Copy link
Copy Markdown

@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: 3

🧹 Nitpick comments (2)
e2e/nwc-multi-pay-invoice.test.ts (1)

57-61: Relax strict errors expectation to reduce E2E flakiness.

Line 59 requires zero per-item errors, which is brittle in network-backed runs. Prefer contract-shape checks plus success presence.

Proposed assertion adjustment
         expect(Array.isArray(multiPayResult.invoices)).toBe(true);
         expect(multiPayResult.invoices.length).toBe(2);
-        expect(multiPayResult.errors).toEqual([]);
-        expect(multiPayResult.invoices[0].preimage).toBeDefined();
-        expect(multiPayResult.invoices[1].preimage).toBeDefined();
+        expect(Array.isArray(multiPayResult.errors)).toBe(true);
+        expect(
+          multiPayResult.invoices.filter((invoice) => invoice.preimage).length,
+        ).toBeGreaterThan(0);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/nwc-multi-pay-invoice.test.ts` around lines 57 - 61, The test is brittle
because it asserts multiPayResult.errors strictly equals an empty array;
instead, verify the contract shape and presence of success: ensure
multiPayResult.errors is an array (use Array.isArray on multiPayResult.errors)
and that its length matches multiPayResult.invoices.length to keep the per-item
error array shape, while keeping the existing checks that
multiPayResult.invoices[0].preimage and multiPayResult.invoices[1].preimage are
defined to assert success presence.
e2e/nwc-multi-pay-keysend.test.ts (1)

51-55: Use contract-safe assertions for multi-keysend results.

Line 53’s errors === [] check is fragile for E2E network variability. Assert shape and successful results instead.

Proposed assertion adjustment
         expect(Array.isArray(multiPayResult.keysends)).toBe(true);
         expect(multiPayResult.keysends.length).toBe(2);
-        expect(multiPayResult.errors).toEqual([]);
-        expect(multiPayResult.keysends[0].preimage).toBeDefined();
-        expect(multiPayResult.keysends[1].preimage).toBeDefined();
+        expect(Array.isArray(multiPayResult.errors)).toBe(true);
+        expect(
+          multiPayResult.keysends.filter((keysend) => keysend.preimage).length,
+        ).toBeGreaterThan(0);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/nwc-multi-pay-keysend.test.ts` around lines 51 - 55, The test currently
asserts multiPayResult.errors equals an empty array which is fragile; instead
assert the result shape and per-entry success: verify multiPayResult.keysends is
an array of length 2, verify multiPayResult.errors is an array (type check) and
that every entry in multiPayResult.keysends has no per-entry error and has a
defined preimage (e.g. check each keysend object for absence/falsey of an error
field and that preimage is defined). Use the existing symbols multiPayResult,
keysends, and errors to locate and update the assertions so they assert
type/shape and per-keysend success rather than strict equality to [].
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@e2e/nwc-get-balance.test.ts`:
- Line 23: The assertion using exact equality on balanceResult.balance vs
BALANCE_MSATS is too strict for a network-backed faucet; change the assertion to
allow a small tolerance or a minimum bound instead of exact match. Update the
test that contains expect(balanceResult.balance).toBe(BALANCE_MSATS) to assert a
range (e.g., greater-than-or-equal to BALANCE_MSATS minus a small delta, or use
toBeGreaterThanOrEqual with a tolerance variable) so BALANCE_MSATS and
balanceResult.balance are compared with a tolerance to avoid flakiness.

In `@e2e/nwc-notifications-payment-received.test.ts`:
- Around line 46-73: The test races because senderClient.payInvoice is called
before the subscription established by receiverClient.subscribeNotifications is
fully active; update subscribeNotifications to provide a readiness signal (e.g.,
return or include a Promise that resolves once the background subscription/loop
has registered the subscription) and then change this test to await that
readiness before calling senderClient.payInvoice; specifically, ensure
receiverClient.subscribeNotifications resolves or exposes a "ready" Promise that
the test awaits prior to invoking senderClient.payInvoice so the notification
cannot be missed.

In `@e2e/nwc-settle-hold-invoice.test.ts`:
- Around line 50-66: The test spawns payPromise via senderClient.payInvoice and
may leave it unawaited on failure, causing unhandled rejections; ensure
payPromise is always awaited or has a rejection handler: keep creating
payPromise, then after calling receiverClient.settleHoldInvoice (or in the catch
block) await payPromise (or await payPromise.catch(() => {})) so the payment
promise is resolved or its rejection is handled in all paths (referencing
payPromise, senderClient.payInvoice, receiverClient.settleHoldInvoice, and the
existing try/catch/finally flow) to avoid leaked unhandled rejections.

---

Nitpick comments:
In `@e2e/nwc-multi-pay-invoice.test.ts`:
- Around line 57-61: The test is brittle because it asserts
multiPayResult.errors strictly equals an empty array; instead, verify the
contract shape and presence of success: ensure multiPayResult.errors is an array
(use Array.isArray on multiPayResult.errors) and that its length matches
multiPayResult.invoices.length to keep the per-item error array shape, while
keeping the existing checks that multiPayResult.invoices[0].preimage and
multiPayResult.invoices[1].preimage are defined to assert success presence.

In `@e2e/nwc-multi-pay-keysend.test.ts`:
- Around line 51-55: The test currently asserts multiPayResult.errors equals an
empty array which is fragile; instead assert the result shape and per-entry
success: verify multiPayResult.keysends is an array of length 2, verify
multiPayResult.errors is an array (type check) and that every entry in
multiPayResult.keysends has no per-entry error and has a defined preimage (e.g.
check each keysend object for absence/falsey of an error field and that preimage
is defined). Use the existing symbols multiPayResult, keysends, and errors to
locate and update the assertions so they assert type/shape and per-keysend
success rather than strict equality to [].
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 88e39087-4e38-4eb9-94cf-15750f2374ac

📥 Commits

Reviewing files that changed from the base of the PR and between 08a6cd7 and 3f50a0f.

📒 Files selected for processing (9)
  • e2e/nwc-cancel-hold-invoice.test.ts
  • e2e/nwc-get-balance.test.ts
  • e2e/nwc-get-budget.test.ts
  • e2e/nwc-get-info.test.ts
  • e2e/nwc-make-hold-invoice.test.ts
  • e2e/nwc-multi-pay-invoice.test.ts
  • e2e/nwc-multi-pay-keysend.test.ts
  • e2e/nwc-notifications-payment-received.test.ts
  • e2e/nwc-settle-hold-invoice.test.ts

Comment thread e2e/nwc-get-balance.test.ts Outdated
Comment thread e2e/nwc-notifications-payment-received.test.ts Outdated
Comment thread e2e/nwc-settle-hold-invoice.test.ts Outdated
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/nwc/NWCClient.ts`:
- Around line 716-719: The Promise initialSubscriptionReady (backed by
pendingInitial) can hang indefinitely if the resolve path in
pendingInitial.resolve is never reached (e.g., repeated failures in
_checkConnected or _selectEncryptionType); change the logic in the notification
subscription setup so the promise is settled on both success and failure:
implement a timeout fallback and a reject path that calls pendingInitial.resolve
or rejects the promise after a configurable timeout, and ensure any
caller-facing return (the unsubscribe function) is returned even when the
initial readiness times out or when _checkConnected/_selectEncryptionType fail;
update references to initialSubscriptionReady, pendingInitial, and the code
paths in _checkConnected/_selectEncryptionType to wire the timeout/reject and to
clean up resources so callers are not left awaiting forever.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9d11214c-10ab-4b7b-94d1-754cc9356625

📥 Commits

Reviewing files that changed from the base of the PR and between 3f50a0f and 5f238a2.

📒 Files selected for processing (4)
  • e2e/nwc-get-balance.test.ts
  • e2e/nwc-notifications-payment-received.test.ts
  • e2e/nwc-settle-hold-invoice.test.ts
  • src/nwc/NWCClient.ts
✅ Files skipped from review due to trivial changes (1)
  • e2e/nwc-settle-hold-invoice.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • e2e/nwc-get-balance.test.ts
  • e2e/nwc-notifications-payment-received.test.ts

Comment thread src/nwc/NWCClient.ts Outdated
@DSanich
Copy link
Copy Markdown
Contributor Author

DSanich commented Apr 15, 2026

@rolznz hello! I hope this PR is still relevant 🙏 Could you please take a look at it? I've corrected coderabbitai's comments in this PR and am currently continuing to work on testing coverage for this repository.

@DSanich DSanich force-pushed the feat/nwc-api-contract-e2e-tests branch from c453c58 to 3ccb8b2 Compare April 15, 2026 11:31
Copy link
Copy Markdown

@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

🧹 Nitpick comments (2)
e2e/nwc-list-transactions-after-payment.test.ts (1)

75-91: Consider polling before asserting incoming/settled to reduce E2E flakes.

payInvoice can complete before the receiver’s transaction view is fully indexed. A short retry loop around listTransactions would make this test more stable in CI/network jitter scenarios.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/nwc-list-transactions-after-payment.test.ts` around lines 75 - 91, The
test currently calls senderClient.payInvoice then immediately calls
receiverClient.listTransactions and asserts matchingTx is incoming/settled,
causing flakes; wrap the list+assert logic in a short retry/poll loop that
re-calls receiverClient.listTransactions (with same params) until a matchingTx
with type === "incoming" and state === "settled" and amount === AMOUNT_MSATS is
found or a timeout (e.g., few seconds / fixed attempts) is reached; ensure the
loop sleeps briefly between attempts and fail the test only after timeout so
matchingTx and its fields are validated reliably.
e2e/nwc-lookup-invoice.test.ts (1)

61-67: Nice contract coverage; consider a small retry around lookupInvoice for stability.

In some relay/backend conditions, immediate post-payment lookup can lag briefly. Retrying lookup for a short window would harden this E2E test against transient timing issues.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/nwc-lookup-invoice.test.ts` around lines 61 - 67, The lookupInvoice call
can race with backend propagation; wrap the receiverClient.lookupInvoice({
payment_hash: invoiceResult.payment_hash }) call in a short retry loop that
polls until the invoice is returned or a timeout is reached (e.g., max 5
attempts with ~200ms delay or a 2s total timeout). Replace the single await
byHash = await receiverClient.lookupInvoice(...) with logic that retries on
null/missing invoice or exceptions and then assert byHash.payment_hash and
byHash.invoice once a non-empty result is received; reference invoiceResult,
senderClient.payInvoice, receiverClient.lookupInvoice, and byHash when locating
where to change the test. Ensure the retry waits use await (e.g.,
Promise+setTimeout) so the test remains async.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@e2e/nwc-multi-pay-invoice.test.ts`:
- Around line 31-37: The test uses a deliberately malformed invoice string
("lnbc1invalidinvoice") which can trigger input validation before the capability
check; replace that with a syntactically valid test invoice (use an existing
fixture like VALID_INVOICE or a helper such as createTestInvoice()) when calling
senderClient.multiPayInvoice({ invoices: [{ invoice: VALID_INVOICE }] }) so the
call reaches the capability-path and you can assert rejects.toMatchObject({
code: "NOT_IMPLEMENTED" }); alternatively, if no valid invoice fixture exists,
pass an empty invoices array (invoices: []) to trigger the capability fallback
without format validation; update the call sites referencing senderInfo.methods
and senderClient.multiPayInvoice accordingly.

---

Nitpick comments:
In `@e2e/nwc-list-transactions-after-payment.test.ts`:
- Around line 75-91: The test currently calls senderClient.payInvoice then
immediately calls receiverClient.listTransactions and asserts matchingTx is
incoming/settled, causing flakes; wrap the list+assert logic in a short
retry/poll loop that re-calls receiverClient.listTransactions (with same params)
until a matchingTx with type === "incoming" and state === "settled" and amount
=== AMOUNT_MSATS is found or a timeout (e.g., few seconds / fixed attempts) is
reached; ensure the loop sleeps briefly between attempts and fail the test only
after timeout so matchingTx and its fields are validated reliably.

In `@e2e/nwc-lookup-invoice.test.ts`:
- Around line 61-67: The lookupInvoice call can race with backend propagation;
wrap the receiverClient.lookupInvoice({ payment_hash: invoiceResult.payment_hash
}) call in a short retry loop that polls until the invoice is returned or a
timeout is reached (e.g., max 5 attempts with ~200ms delay or a 2s total
timeout). Replace the single await byHash = await
receiverClient.lookupInvoice(...) with logic that retries on null/missing
invoice or exceptions and then assert byHash.payment_hash and byHash.invoice
once a non-empty result is received; reference invoiceResult,
senderClient.payInvoice, receiverClient.lookupInvoice, and byHash when locating
where to change the test. Ensure the retry waits use await (e.g.,
Promise+setTimeout) so the test remains async.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6bbba78d-6dfe-4861-87d4-77effa307ced

📥 Commits

Reviewing files that changed from the base of the PR and between 5f238a2 and 3ccb8b2.

📒 Files selected for processing (14)
  • e2e/nwc-cancel-hold-invoice.test.ts
  • e2e/nwc-faucet.test.ts
  • e2e/nwc-get-balance.test.ts
  • e2e/nwc-get-budget.test.ts
  • e2e/nwc-get-info.test.ts
  • e2e/nwc-list-transactions-after-payment.test.ts
  • e2e/nwc-lookup-invoice.test.ts
  • e2e/nwc-make-hold-invoice.test.ts
  • e2e/nwc-multi-pay-invoice.test.ts
  • e2e/nwc-multi-pay-keysend.test.ts
  • e2e/nwc-notifications-payment-received.test.ts
  • e2e/nwc-settle-hold-invoice.test.ts
  • e2e/nwc-sign-message.test.ts
  • src/nwc/NWCClient.ts
✅ Files skipped from review due to trivial changes (3)
  • e2e/nwc-get-balance.test.ts
  • e2e/nwc-get-budget.test.ts
  • e2e/nwc-notifications-payment-received.test.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • e2e/nwc-get-info.test.ts
  • src/nwc/NWCClient.ts
  • e2e/nwc-multi-pay-keysend.test.ts
  • e2e/nwc-settle-hold-invoice.test.ts
  • e2e/nwc-make-hold-invoice.test.ts
  • e2e/nwc-cancel-hold-invoice.test.ts

Comment thread e2e/nwc-multi-pay-invoice.test.ts Outdated
@rolznz
Copy link
Copy Markdown
Member

rolznz commented Apr 15, 2026

Hi @DSanich , sorry I somehow missed this, thanks for adding extra tests! I would prefer if possible for the changes to the NWCClient to be moved to a new PR as I think we need to review those separately and am not sure that's the best place to do it.

@DSanich
Copy link
Copy Markdown
Contributor Author

DSanich commented Apr 16, 2026

Hello @rolznz! Yes sure

@DSanich DSanich force-pushed the feat/nwc-api-contract-e2e-tests branch from 3ccb8b2 to f127441 Compare April 16, 2026 06:28
Copy link
Copy Markdown

@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: 3

♻️ Duplicate comments (1)
e2e/nwc-multi-pay-invoice.test.ts (1)

31-37: ⚠️ Potential issue | 🟡 Minor

Use a valid invoice for the unsupported-capability probe.

Line 34 uses a malformed invoice string, so rejection can come from input validation instead of capability handling. This makes the NOT_IMPLEMENTED assertion flaky.

Proposed fix
         if (!senderInfo.methods.includes("multi_pay_invoice")) {
+          const probeInvoice = await receiverClient.makeInvoice({
+            amount: AMOUNT_MSATS,
+            description: "E2E multi_pay_invoice capability probe",
+          });
           await expect(
             senderClient.multiPayInvoice({
-              invoices: [{ invoice: "lnbc1invalidinvoice" }],
+              invoices: [{ invoice: probeInvoice.invoice }],
             }),
           ).rejects.toMatchObject({ code: "NOT_IMPLEMENTED" });
           return;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/nwc-multi-pay-invoice.test.ts` around lines 31 - 37, The test uses a
malformed invoice ("lnbc1invalidinvoice") when calling
senderClient.multiPayInvoice, which can trigger input validation instead of the
capability check; update the probe to supply a syntactically valid Lightning
invoice (e.g., generate or use a known-valid dummy/invoice string) in the
invoices array so the call reaches capability handling; ensure the call remains
under the branch checking senderInfo.methods and that the assertion still
expects rejects.toMatchObject({ code: "NOT_IMPLEMENTED" }) from
senderClient.multiPayInvoice.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@e2e/nwc-cancel-hold-invoice.test.ts`:
- Line 56: The test currently only asserts the invoice format; extend it to also
assert that the returned hold invoice echoes the requested payment hash by
adding an expectation comparing holdInvoiceResult.payment_hash (or the property
name used on the response) to the original requestedPaymentHash (or the variable
used when creating the hold invoice) — locate the assertion after
expect(holdInvoiceResult.invoice).toMatch(/^ln/) and add
expect(holdInvoiceResult.payment_hash).toBe(requestedPaymentHash) (adjust
property/variable names to match the test).
- Around line 44-47: The test is over-constraining the error from
receiverClient.cancelHoldInvoice by asserting only code "NOT_IMPLEMENTED";
update the assertion around cancelHoldInvoice({ payment_hash: paymentHash })
(the call guarded by hasHoldMethods) to accept both "NOT_IMPLEMENTED" and
"RESTRICTED" (or otherwise a regex/collection that matches either code) so
wallets that signal unavailable-by-scope with "RESTRICTED" do not fail the test.
- Around line 65-69: Replace the fixed 1500ms sleep with a bounded
retry/condition wait that polls the invoice state until it is in the hold state
(or a timeout is reached) before calling receiverClient.cancelHoldInvoice;
specifically, remove the setTimeout and implement a small helper loop that
repeatedly calls the invoice lookup method (e.g., receiverClient.getInvoice or
lookupInvoice with payment_hash/paymentHash) at short intervals (e.g.,
100-300ms) for a maximum duration (e.g., 5-10s), proceed to call
receiverClient.cancelHoldInvoice({ payment_hash: paymentHash }) only when the
invoice status indicates it is held, and throw/assert a clear timeout error if
the condition is not met within the bound.

---

Duplicate comments:
In `@e2e/nwc-multi-pay-invoice.test.ts`:
- Around line 31-37: The test uses a malformed invoice ("lnbc1invalidinvoice")
when calling senderClient.multiPayInvoice, which can trigger input validation
instead of the capability check; update the probe to supply a syntactically
valid Lightning invoice (e.g., generate or use a known-valid dummy/invoice
string) in the invoices array so the call reaches capability handling; ensure
the call remains under the branch checking senderInfo.methods and that the
assertion still expects rejects.toMatchObject({ code: "NOT_IMPLEMENTED" }) from
senderClient.multiPayInvoice.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 317b11c4-0bf4-48f7-9c46-62f09a911622

📥 Commits

Reviewing files that changed from the base of the PR and between 3ccb8b2 and f127441.

📒 Files selected for processing (12)
  • e2e/nwc-cancel-hold-invoice.test.ts
  • e2e/nwc-faucet.test.ts
  • e2e/nwc-get-balance.test.ts
  • e2e/nwc-get-budget.test.ts
  • e2e/nwc-get-info.test.ts
  • e2e/nwc-list-transactions-after-payment.test.ts
  • e2e/nwc-lookup-invoice.test.ts
  • e2e/nwc-multi-pay-invoice.test.ts
  • e2e/nwc-multi-pay-keysend.test.ts
  • e2e/nwc-notifications-payment-received.test.ts
  • e2e/nwc-settle-hold-invoice.test.ts
  • e2e/nwc-sign-message.test.ts
✅ Files skipped from review due to trivial changes (2)
  • e2e/nwc-lookup-invoice.test.ts
  • e2e/nwc-get-balance.test.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • e2e/nwc-faucet.test.ts
  • e2e/nwc-get-budget.test.ts
  • e2e/nwc-get-info.test.ts
  • e2e/nwc-list-transactions-after-payment.test.ts
  • e2e/nwc-sign-message.test.ts
  • e2e/nwc-multi-pay-keysend.test.ts
  • e2e/nwc-notifications-payment-received.test.ts
  • e2e/nwc-settle-hold-invoice.test.ts

Comment thread e2e/nwc-cancel-hold-invoice.test.ts Outdated
Comment thread e2e/nwc-cancel-hold-invoice.test.ts
Comment thread e2e/nwc-cancel-hold-invoice.test.ts Outdated
Comment thread e2e/nwc-cancel-hold-invoice.test.ts Outdated
Comment thread e2e/nwc-get-info.test.ts Outdated
Comment thread e2e/nwc-multi-pay-invoice.test.ts Outdated
@DSanich
Copy link
Copy Markdown
Contributor Author

DSanich commented Apr 16, 2026

@rolznz I've implemented your suggested changes. I'd be happy to receive a second review 🙏

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.

2 participants