Skip to main content

Migration Guide (V2 → V3)

This guide helps integrators move from the V2 proof flow to the V3 attestation flow with minimal changes.

Key differences

  • Off-chain verification
    • V2: proof JSON (e.g., Reclaim/TLSN) was parsed/validated on-chain by per‑platform verifier contracts.
    • V3: proofs are validated off-chain by the Attestation Service, which emits a signed PaymentAttestation verified by a single UnifiedPaymentVerifier on-chain.
  • On-chain interface
    • V2: multiple verifiers per platform with heterogeneous calldata.
    • V3: one paymentProof encoding a PaymentAttestation and a fixed snapshot format.
  • Intent signing
    • V2: simpler intent signing.
    • V3: the gating signature binds more fields (payment method, fiat currency, conversion rate, orchestrator/escrow addresses).

What stays the same

  • Non-custodial: Escrow only holds and transfers funds.
  • PeerAuth: proof generation UX and API are the same.
  • Currency/method hashing: still keccak256 bytes32 on-chain.

API changes you'll notice

  • Gating (Curator): use the v2 verify endpoint with the expanded request.
  • Quoter: response now includes deposit success metrics and optional filters.

On-chain calls (before/after)

  • Signal
    • V2: Escrow.signalIntent(depositId, amount, to, verifierAddr, fiatCurrency, gatingSig)
    • V3: Orchestrator.signalIntent({ escrow, depositId, amount, to, paymentMethod, fiatCurrency, conversionRate, gatingServiceSignature, signatureExpiration, referrer, referrerFee, postIntentHook, data })
  • Fulfill
    • V2: Escrow.fulfillIntent(bytes proof, bytes32 intentHash) with proof JSON bytes
    • V3: Orchestrator.fulfillIntent({ paymentProof: abi.encode(PaymentAttestation), intentHash, verificationData, postIntentHookData })

V3 Contract Upgrade

The V3 contracts were upgraded from Escrow/Orchestrator to EscrowV2/OrchestratorV2. If you integrated against the original V3 contracts, here are the breaking changes:

Intent Parameters

  • referrer (address) + referrerFee (uint256) → referralFees[] (array of IReferralFee.ReferralFee). Supports multiple referral recipients with individual fees.
  • IPostIntentHook postIntentHookIPostIntentHookV2 postIntentHook. The V2 hook interface uses HookExecutionContext instead of (Intent, amountNetFees, data).
  • New field: bytes preIntentHookData — Ephemeral data passed to pre-intent hooks during signalIntent.

New Escrow Address

  • New deposits should go to EscrowV2 (0x777777779d229cdF3110e9de47943791c26300Ef).
  • The legacy Escrow (0x2f121CDDCA6d652f35e8B3E560f9760898888888) still holds active deposits but is deprecated.

Orchestrator Authorization

  • OrchestratorRegistry replaces the single orchestrator address on Escrow. Multiple orchestrators can be authorized on EscrowV2.
  • Use OrchestratorV2 (0x888888359E981B5225CA48fbCdCeff702FC3b888) for new intents.

Verification

  • UnifiedPaymentVerifierV2 (0x46A58Dc65587D4D7B8198C6A25eEdf5b2535Da94) is the production verifier. The legacy UnifiedPaymentVerifier is only used by the deprecated Orchestrator.

New Optional Features

  • Pre-intent hooks: two hook slots per deposit (generic + whitelist) for on-chain access control. See Pre-Intent Hooks.
  • Oracle rate configuration: per-currency oracle adapters for automatic rate floor adjustment.
  • Delegated rate management: opt into RateManagerV1 for programmatic rate updates with fee sharing.
  • Manager fees: rate managers can charge fees (capped at 5%) distributed at fulfillment.