Unified Payment Verifier
Overview
UnifiedPaymentVerifier verifies standardized off‑chain attestations produced by the Attestation Service. It validates EIP‑712 signatures via a pluggable AttestationVerifier, enforces snapshot consistency with on‑chain intent state, prevents replay via nullifiers, and caps the release amount to the signaled intent amount.
Typed Data
- Primary type:
PaymentAttestation(bytes32 intentHash,uint256 releaseAmount,bytes32 dataHash) - Domain (EIP‑712):
name = "UnifiedPaymentVerifier"version = "1"chainId = block.chainidverifyingContract = address(this)
Attestation struct passed on‑chain
struct PaymentAttestation {
bytes32 intentHash; // binds to on-chain intent
uint256 releaseAmount; // token amount to release (pre-fees)
bytes32 dataHash; // keccak256(data)
bytes[] signatures; // witness signatures
bytes data; // abi.encode(PaymentDetails, IntentSnapshot)
bytes metadata; // optional; not signed
}
Data payload
struct PaymentDetails {
bytes32 method; // payment method (bytes32)
bytes32 payeeId; // hashed off-chain recipient id
uint256 amount; // smallest fiat unit (e.g., cents)
bytes32 currency; // fiat code hash
uint256 timestamp; // ms epoch
bytes32 paymentId; // hashed provider transaction id
}
struct IntentSnapshot {
bytes32 intentHash;
uint256 amount; // signaled token amount
bytes32 paymentMethod; // bytes32
bytes32 fiatCurrency; // bytes32
bytes32 payeeDetails; // bytes32 (must match PaymentDetails.payeeId)
uint256 conversionRate; // 1e18
uint256 signalTimestamp; // seconds
uint256 timestampBuffer; // ms/seconds window
}
Verification Flow
- Compute struct hash for
(intentHash, releaseAmount, dataHash). - Compute domain‑bound digest and verify witness
signaturesviaAttestationVerifier. - Check
keccak256(attestation.data) == dataHash. - Decode
(PaymentDetails, IntentSnapshot)and validate snapshot against on‑chainOrchestrator.getIntent(intentHash)(amount, method, currency, conversionRate, signalTimestamp) andEscrow.getDepositPaymentMethodData(...).payeeDetails. - Nullify the payment:
keccak256(paymentMethod || paymentId); revert if already used. - Cap
releaseAmounttointent.amount.
Returns PaymentVerificationResult { success, intentHash, releaseAmount } to the Orchestrator.
Governance & Config
Provided by BaseUnifiedPaymentVerifier:
getPaymentMethods()— list of supported methods (bytes32).addPaymentMethod(method)/removePaymentMethod(method)— owner‑only.setAttestationVerifier(address)— update the witness verifier; emitsAttestationVerifierUpdated.