The Signing Service is a recommended architectural pattern for security and domain separation. While the x402 spec does not mandate a specific implementation, separating signing logic from the Client Agent allows for the use of secure environments like HSMs, MPC, or hardware wallets.
Implementation Options:
- Separate Signing Service (Recommended): The Client Agent communicates with an independent service. This creates a clear security boundary.
- Integrated Signing: The Client Agent handles signing directly. This is spec-compliant but offers less domain separation.
Core Responsibility:
Receive an x402PaymentRequiredResponse, select an appropriate PaymentRequirements option from the accepts list, sign it using a private key/account, and return a PaymentPayload.
# Example pattern for a Signing Service
class SigningServiceOperations:
def __init__(self, account: Account):
self._account = account
async def process_payment_required(
self,
payment_required: x402PaymentRequiredResponse,
max_value: Optional[int] = None
) -> PaymentPayload:
# 1. Select requirement
selected_requirement = self._select_payment_requirement(payment_required.accepts)
# 2. Sign requirement
payment_payload = await process_payment(selected_requirement, self._account, max_value)
return payment_payload
def _select_payment_requirement(
self,
accepts: list[PaymentRequirements]
) -> PaymentRequirements:
return accepts[0] # Implementation specific selection logic