feat: Add MPP client-side support#1
Conversation
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>
There was a problem hiding this comment.
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(), andparse_payment_challenge()(L402 preferred, MPP fallback). - Updates
L402Client.access()/pay_and_access()to retry with eitherL402 ...orPayment ... preimage="..."Authorization headers. - Exports new parsing helpers from
le_agent_sdk.l402and 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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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>
There was a problem hiding this comment.
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.
Summary
MppChallengedataclass forPaymentscheme challengesparse_mpp_challenge()andparse_payment_challenge()(L402 preferred, MPP fallback)L402Client.access()andpay_and_access()handle both protocolsL402ProducerClient.verify_payment()macaroon now optional for MPPPayment method="lightning", preimage="<hex>"for MPPTest plan
🤖 Generated with Claude Code