Skip to content

feat: Add MPP client-side support#1

Merged
refined-element merged 9 commits intomasterfrom
feat/mpp-client-support
Mar 21, 2026
Merged

feat: Add MPP client-side support#1
refined-element merged 9 commits intomasterfrom
feat/mpp-client-support

Conversation

@refined-element
Copy link
Owner

Summary

  • MppChallenge dataclass for Payment scheme challenges
  • parse_mpp_challenge() and parse_payment_challenge() (L402 preferred, MPP fallback)
  • L402Client.access() and pay_and_access() handle both protocols
  • L402ProducerClient.verify_payment() macaroon now optional for MPP
  • Auth: Payment method="lightning", preimage="<hex>" for MPP

Test plan

  • All 100 tests pass (12 new MPP tests)
  • Verify L402-only servers still work (regression)

🤖 Generated with Claude Code

Parse WWW-Authenticate: Payment headers per IETF draft-ryan-httpauth-payment.
MppChallenge, parse_mpp_challenge(), parse_payment_challenge().
Prefer L402 when both present; fall back to MPP. Optional macaroon in verify.

12 new tests, all 100 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 21, 2026 05:31
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds client-side MPP (“Payment … method=lightning”) support alongside existing L402 handling, including header parsing and request retry authorization, and updates producer-side verification to allow MPP-style verification.

Changes:

  • Introduces MppChallenge, parse_mpp_challenge(), and parse_payment_challenge() (L402 preferred, MPP fallback).
  • Updates L402Client.access() / pay_and_access() to retry with either L402 ... or Payment ... preimage="..." Authorization headers.
  • Exports new parsing helpers from le_agent_sdk.l402 and adds MPP-focused tests.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
tests/test_l402_client.py Adds unit tests for MPP parsing and L402-vs-MPP selection logic.
src/le_agent_sdk/l402/client.py Implements MPP challenge parsing, unified challenge parsing, and dual-protocol Authorization header construction; makes producer verification accept optional macaroon.
src/le_agent_sdk/l402/init.py Exposes MPP-related public API symbols.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Restore backward-compatible parameter order for verify_payment()
  (macaroon first, preimage as keyword-only) to avoid breaking callers
- Add preimage validation to pay_and_access() matching access() behavior
- Scope MPP realm/amount parsing to Payment segment only to prevent
  cross-scheme attribute capture from multi-challenge headers
- Add test for realm scoping with mixed Bearer + Payment headers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Properly delimit Payment challenge segment by splitting on auth-scheme
  boundaries, preventing realm/amount leakage from other schemes (e.g.
  trailing Bearer realm)
- Restore verify_payment() backward compatibility: both macaroon and
  preimage are positional parameters again (no keyword-only restriction)
- Add .strip() to all captured MPP challenge values for consistency with
  parse_l402_challenge()
- Add test for trailing scheme not leaking into Payment challenge

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Make preimage required (keyword-only) in verify_payment() to prevent
  accidental calls with empty preimage
- Distinguish missing vs empty WWW-Authenticate header in
  parse_payment_challenge() with specific error messages
- Add try/except wrapping around pay_invoice_callback in pay_and_access()
  for consistent error handling matching access()
- Add 7 unit tests for verify_payment() covering L402 and MPP payload
  formation, TypeError on missing args, API errors, and whitespace stripping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Restore backward-compatible positional args in verify_payment(macaroon, preimage)
- Distinguish macaroon=None (MPP) from empty/whitespace macaroon (ValueError)
- Add negative lookbehind to MPP regexes to prevent substring parameter matches
- Add async tests for 402->pay->retry flow in access() for both L402 and MPP
- Add async tests for 402->pay->retry flow in pay_and_access() for both L402 and MPP
- Add tests for empty/whitespace macaroon validation and positional backward compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Use RFC-compliant tchar boundary matching (^|[\s,]) for MPP regexes
  instead of incomplete negative lookbehind
- Redact preimage from info-level logs to prevent credential leakage;
  full value only at debug level
- Remove unused L402VerifyResponse import from test module
- Support both quoted and unquoted (bare token) auth-param values in
  MPP challenge parsing per HTTP auth header grammar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Tighten _MPP_METHOD_RE regex to enforce exact "lightning" value boundary,
preventing false positives like method="lightning2" or method=lightningXYZ.
Add tests verifying both quoted and unquoted suffixed variants are rejected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Add missing '=' delimiter in _CHALLENGE_RE for L402 auth-param parsing
- Add missing '=' delimiter in MPP regex patterns (_MPP_INVOICE_RE, _MPP_METHOD_RE, _MPP_AMOUNT_RE, _MPP_REALM_RE)
- Stop logging full preimage at DEBUG level; log only 8-char prefix for security

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@refined-element refined-element requested a review from Copilot March 21, 2026 06:50
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Use call_args.kwargs["json"] instead of positional tuple access in
  verify_payment tests (threads PRRT_kwDORnWTtc513k28, PRRT_kwDORnWTtc513k3Q)
- Remove contradictory log message about DEBUG logging showing full
  preimage when it only shows the prefix (thread PRRT_kwDORnWTtc513k3E)
- Add proper preimage validation in verify_payment: reject empty strings,
  whitespace-only, and non-string values (thread PRRT_kwDORnWTtc513k3J)
- Use .kwargs access pattern consistently for retry_call headers in tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@refined-element refined-element requested a review from Copilot March 21, 2026 06:59
@refined-element refined-element merged commit 988ccad into master Mar 21, 2026
5 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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