Skip to content

feat(evm): add shielded payment mechanism (privacy pool unshield)#1956

Open
mmchougule wants to merge 3 commits intox402-foundation:mainfrom
mmchougule:impl/shielded-evm-typescript
Open

feat(evm): add shielded payment mechanism (privacy pool unshield)#1956
mmchougule wants to merge 3 commits intox402-foundation:mainfrom
mmchougule:impl/shielded-evm-typescript

Conversation

@mmchougule
Copy link
Copy Markdown

Summary

Adds ShieldedEvmClient, ShieldedEvmFacilitator, and ShieldedEvmServer implementing assetTransferMethod: "shielded" for the exact scheme on EVM.

Agents withdraw tokens from an on-chain privacy pool (e.g., Railgun) directly to the merchant's payTo address. The pool contract verifies the ZK proof and checks nullifiers on-chain. The facilitator confirms the resulting ERC-20 Transfer event matches the payment requirements.

Reference implementation uses a deployed privacy pool on Base (Railgun) with on-chain nullifier tracking for double-spend prevention.

Implementation

Client (ShieldedEvmClient): Takes an injected UnshieldFn — SDK-agnostic, any privacy pool works. Calls unshield and returns { txHash }.

Facilitator (ShieldedEvmFacilitator):

  • Validates txHash format, checks replay store
  • Fetches tx receipt — non-reverted means pool accepted the ZK proof
  • Parses ERC-20 Transfer events: from must be a registered pool contract, to must match payTo, value >= required
  • Tracks txHash + nullifiers in replay store
  • Settle re-verifies before confirming (matches existing EVM/SVM pattern)
  • Client-driven settlement — facilitator is verify-only

Server (ShieldedEvmServer): Parses prices, enhances requirements with assetTransferMethod: "shielded" and poolContracts.

Tests

26 unit tests covering:

  • Valid payment verification
  • Invalid txHash, reverted tx, wrong pool, wrong recipient, wrong amount, wrong token
  • txHash replay prevention
  • Nullifier replay prevention (defense-in-depth on top of on-chain nullifier set)
  • Settle re-verification and settle failure
  • Server price parsing and requirement enhancement
  • Client payload creation and error propagation

All 365 existing tests still pass.

Files

typescript/packages/mechanisms/evm/src/shielded/
├── types.ts, constants.ts, index.ts
├── client/scheme.ts
├── facilitator/scheme.ts, errors.ts
└── server/scheme.ts

typescript/packages/mechanisms/evm/test/unit/shielded/
├── client.test.ts
├── facilitator.test.ts
└── server.test.ts

Spec: #1951
Closes #1953

Adds `specs/schemes/exact/scheme_exact_evm_shielded.md` — the specification
for a new `assetTransferMethod: "shielded"` under the existing `exact` scheme
on EVM chains.

This enables privacy-preserving x402 payments where the payer's identity is
hidden behind a ZK proof verified by an on-chain privacy pool (e.g., Railgun).
The facilitator verifies payments by inspecting the standard ERC-20 Transfer
event emitted during unshield — no viewing keys or trial decryption required.

Key properties:
- Settlement: Client-driven (unshield on-chain before verification)
- Verification: ERC-20 Transfer event from registered pool contract
- Privacy: Sender hidden via ZK proof; amount visible to facilitator
- Token: Any ERC-20 supported by the privacy pool (USDC, USDT, DAI)
- Gas: Client pays, or gasless via ERC-4337

This is designed to be general — works with any privacy pool that emits
standard ERC-20 Transfer events, not tied to a specific implementation.

Relates to x402-foundation#1633
Implements SchemeNetworkClient, SchemeNetworkFacilitator, and
SchemeNetworkServer for assetTransferMethod: "shielded" on EVM.

Client calls an injected UnshieldFn (SDK-agnostic) to withdraw tokens
from a privacy pool to the payTo address. Facilitator verifies the
resulting ERC-20 Transfer event: from must be a registered pool
contract, to must match payTo, value must meet the required amount.
Settlement is client-driven — facilitator is verify-only.

Verification flow:
- Validate txHash format and check replay store
- Fetch tx receipt (non-reverted = pool accepted the ZK proof)
- Parse Transfer event logs against pool contract allowlist
- Track txHash + nullifiers in replay store for double-spend prevention
- Settle re-verifies before confirming (follows EVM/SVM pattern)

26 unit tests covering: valid payment, invalid hash, reverted tx,
wrong pool, wrong recipient, wrong amount, wrong token, txHash replay,
nullifier replay, settle re-verification, settle failure, server price
parsing, requirement enhancement, client payload creation.

Relates to x402-foundation#1953
@github-actions github-actions bot added specs Spec changes or additions typescript sdk Changes to core v2 packages labels Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sdk Changes to core v2 packages specs Spec changes or additions typescript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add shielded EVM payments as assetTransferMethod for exact scheme

1 participant