Skip to content

feat(sdk): Add server co-signing support to TypeScript and Python SDKs#60

Open
pcarranzav wants to merge 13 commits intopcv/cosigner-validatorfrom
pcv/cosigner-sdk-updates
Open

feat(sdk): Add server co-signing support to TypeScript and Python SDKs#60
pcarranzav wants to merge 13 commits intopcv/cosigner-validatorfrom
pcv/cosigner-sdk-updates

Conversation

@pcarranzav
Copy link
Member

Summary

Adds server co-signing support to both TypeScript and Python SDKs, enabling smart account wallets to use server-provided co-signatures for enhanced security.

Changes

TypeScript

  • Add ERC3009AuthorizationData and ServerAuthorizationData Effect schemas
  • Update AgentPaymentAuthResponse with payment field
  • Add createCoSignedPayment() and encodeCoSignedERC1271Signature()
  • Update SmartAccountWallet.createPayment() to support serverAuthorization
  • Update AmpersendTreasurer to pass server authorization
  • Update X402Wallet interface with optional parameter

Python

  • Add ERC3009AuthorizationData and ServerAuthorizationData Pydantic models
  • Update ApiResponseAgentPaymentAuthorization with payment field
  • Add smart_account_create_cosigned_payment() and encode_cosigned_1271_signature()
  • Update SmartAccountWallet and AmpersendTreasurer
  • Update X402Wallet protocol with optional parameter

Backward Compatibility

✅ Server authorization is optional - existing code works unchanged
✅ Full-access keys and EOA wallets ignore the parameter

Testing

TypeScript: pnpm build succeeds
Python: Syntax validated

🤖 Generated with Claude Code

pcarranzav and others added 3 commits March 11, 2026 11:49
…ypes

- Add ERC3009AuthorizationData schema for TransferWithAuthorization data
- Add ServerAuthorizationData schema for server co-signature responses
- Extend AgentPaymentAuthResponse with payment field
- Supports both co-signed and full-access authorization flows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update X402Wallet interface with optional serverAuthorization parameter
- Add createCoSignedPayment() function for co-signed keys
- Update SmartAccountWallet.createPayment() to branch on serverAuthorization
- Update AmpersendTreasurer to pass server authorization from API response
- Update AccountWallet to accept (and ignore) serverAuthorization parameter
- Add encodeCoSignedERC1271Signature() helper for dual-signature encoding

Supports both co-signed and full-access key flows with backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add ERC3009AuthorizationData and ServerAuthorizationData Pydantic models
- Update ApiResponseAgentPaymentAuthorization with payment field
- Add smart_account_create_cosigned_payment() function
- Add encode_cosigned_1271_signature() helper for dual-signature encoding
- Update SmartAccountWallet.create_payment() to branch on server_authorization
- Update AmpersendTreasurer to pass server authorization from API response
- Update X402Wallet protocol and AccountWallet for optional parameter

Supports both co-signed and full-access key flows with backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pcarranzav pcarranzav force-pushed the pcv/cosigner-sdk-updates branch from 50bbd43 to 25208e9 Compare March 11, 2026 14:54
pcarranzav and others added 3 commits March 11, 2026 12:34
- Fix Python imports for mypy (use explicit eth_abi.abi, eth_utils.conversions)
- Fix Python formatting (multi-line for long error messages)
- Fix TypeScript formatting (prettier)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add cast() for to_hex return type
- Use eth_utils.conversions for to_hex import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
session_key: str
smart_account_address: str
validator_address: str = OWNABLE_VALIDATOR
cosigner_validator_address: str | None = None
Copy link
Member Author

Choose a reason for hiding this comment

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

This should default to our cosigner validator address


# Dotenv file
.env
foundry.lock
Copy link
Member Author

Choose a reason for hiding this comment

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

this should not be gitignored

// while x402 PaymentRequirements uses specific network literals. Runtime compatible.
const payment = await this.wallet.createPayment(authorizedReq.requirement as any)
// Check if server provided co-signature (for co-signed keys)
let payment
Copy link
Member Author

Choose a reason for hiding this comment

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

todo: add a type

// Co-signed path: use server-provided authorization data and signature
payment = await this.wallet.createPayment(
response.payment.requirement as any,
response.payment as any, // ServerAuthorizationData
Copy link
Member Author

Choose a reason for hiding this comment

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

can we avoid using any here?

pcarranzav and others added 4 commits March 13, 2026 11:07
- Add COSIGNER_VALIDATOR constant to Python constants
- Set cosigner_validator_address default to COSIGNER_VALIDATOR
- Extract EIP-712 types to shared constants (Python and TypeScript)
- Add PaymentPayload type annotation in treasurer
- Replace 'any' with proper ServerAuthorizationData type
- Remove foundry.lock from .gitignore
- Add foundry.lock to repo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update X402Wallet interface to use ServerAuthorizationData instead of unknown
- Update AccountWallet to use ServerAuthorizationData instead of Any
- Apply to both TypeScript and Python implementations
- Improves type safety while keeping implementation correct

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use x402's PaymentRequirements consistently in wallet interfaces
- Replace 'as any' with 'as PaymentRequirements' at schema boundary
- Use explicit AmpersendPaymentRequirements alias for Effect Schema type
- Add comment explaining the zod/Effect Schema type boundary cast
- Fix onPaymentRequired parameter type to match interface

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pcarranzav pcarranzav marked this pull request as ready for review March 14, 2026 14:09
pcarranzav and others added 3 commits March 14, 2026 11:12
- Construct ServerAuthorizationData from PaymentData (different types)
- Use alias field names for Pydantic model construction
- Fix ruff formatting on account wallet.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move ERC3009AuthorizationData and ServerAuthorizationData from
ampersend/types.py to x402/types.py to break circular import chain:
x402/wallet.py -> ampersend/types.py -> ampersend/__init__.py ->
ampersend/treasurer.py -> x402/__init__.py -> x402/wallet.py

Re-export from ampersend/types.py for backward compatibility.
Update all imports to use canonical x402/types.py location.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Wallet

Add COSIGNER_VALIDATOR to TypeScript constants (matching Python SDK) and
use it as default for coSignerValidatorAddress in SmartAccountWallet.
This removes the need to explicitly pass the address since it's the same
on all chains (CREATE2 deployed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant