feat: implement full fee payer support#62
Merged
brendanjryan merged 8 commits intomainfrom Feb 19, 2026
Merged
Conversation
Port of tempoxyz/mpp-rs#71 to pympp. Client side: - When feePayer: true in challenge, use expiring nonces (nonce_key=U256::MAX, nonce=0) with valid_before=now+25s for replay protection - Set fee_token=None and add placeholder fee_payer_signature (0x00) Server side: - Add _cosign_as_fee_payer() that decodes 0x76 tx, recovers sender via ecrecover, sets fee_token, and co-signs with domain 0x78 - _verify_transaction() co-signs locally when fee_payer account is configured on the method, falls back to external fee payer service otherwise Factory: - Add fee_payer parameter to tempo() and TempoMethod - Wire up _method backlink so ChargeIntent can access fee_payer account Tested end-to-end: pympp client -> pympp server with fee payer co-signing on testnet (chain 42431).
- Add _validate_cosign_calls() to reject transactions that don't match the charge request (currency, recipient, amount, selector) before the server co-signs them. Prevents the fee payer from being used as an open gas relay. - Move attrs import to top-level in client.py and intents.py (hard dep). - Add 11 tests: cosign roundtrip, malformed input rejection, call validation (wrong currency/amount/recipient), and fee_payer propagation through tempo() factory.
brendanjryan
commented
Feb 19, 2026
|
|
||
| try: | ||
| cosigned = tx_to_sign.sign(self.fee_payer.private_key, for_fee_payer=True) | ||
| except Exception as err: |
Collaborator
Author
There was a problem hiding this comment.
can I tighten this up at all?
…ign_calls, simplify fee_token
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port of tempoxyz/mpp-rs#71 to pympp.
Changes
Client side (
client.py)feePayer: truein challenge, use expiring nonces (nonce_key=U256::MAX,nonce=0) withvalid_before=now+25sfor replay protectionfee_token=Noneand add placeholderfee_payer_signature(0x00)Server side (
intents.py)_cosign_as_fee_payer()method: decodes 0x76 tx, recovers sender via ecrecover, setsfee_token, co-signs with domain0x78_verify_transaction()co-signs locally whenfee_payeraccount is configured on the method, falls back to external fee payer service otherwiseFactory (
client.pytempo())fee_payerparameter totempo()andTempoMethod_methodbacklink soChargeIntentcan accessfee_payeraccountTesting
mpp.sh/api/ping/paid✅Usage