Skip to main content

Attestation Service

The Attestation Service verifies fiat payments off-chain and returns a signed EIP-712 PaymentAttestation that UnifiedPaymentVerifierV4 accepts on-chain. It also signs identity attestations for seller registration and dispute attestations for Stake to Take.

Production URL: https://attestation-service.zkp2p.xyz (Base mainnet). @zkp2p/zkp2p-attestation targets it with createNitroAttestationClient({ environment: "production" }).

Trust model​

  • Enclave. The service runs inside an AWS Nitro Enclave. Payment evidence, seller credentials and identity evidence are decrypted, checked and signed only inside the enclave.
  • Signing key. The EIP-712 signing key is stored encrypted under AWS KMS. KMS releases it only to an enclave whose Nitro attestation document carries the expected PCR8, the measurement of the certificate Peer signs enclave images with. The plaintext key exists only in enclave memory.
  • Client checks. Clients call GET /attestation?nonce=... and verify the AWS-signed attestation document and its PCR8 against the pin in @zkp2p/zkp2p-attestation before they encrypt session material to the enclave or trust a signature.
  • On-chain checks. UnifiedPaymentVerifierV4 accepts only signatures from the witness set on MultiAttestationVerifier.
  • What you trust. AWS Nitro, and the enclave images Peer signs. Peer controls the signing certificate, so a malicious image signed by Peer could produce false attestations. See Risks.

Endpoints​

EndpointPurpose
GET /attestation?nonce=...Nitro attestation document bound to your nonce, with the enclave's upload public key
POST /buyer/verify/:platform/:actionTypeBuyer TEE Verification: verify a buyer's payment
GET /buyer/supportedRegistered buyer verifiers and the typed-data spec
POST /seller/credentials/:platformSeller Autopilot: validate seller credentials, return an encrypted bundle
POST /identityProve a live payment-platform account and return an IdentityAttestation
POST /dispute/verify/:platform/:actionTypeVerify a Venmo or PayPal dispute email and return a DisputeAttestation
GET /dispute/supportedRegistered dispute verifiers and their typed-data specs
GET /healthService health
GET /docsOpenAPI reference

For Seller Autopilot, Peer's API stores the encrypted credential bundle and asks the enclave to verify seller-side payments. It cannot decrypt the bundle.

Payment attestations​

Buyer TEE Verification and Seller Autopilot both normalize the observed payment, check it against the intent, and return the same output: the signer, the signature, the typed PaymentAttestation values, the encoded payload and unsigned metadata naming the source path (buyer-tee or seller-tee). The client passes abi.encode(PaymentAttestation) as paymentProof to OrchestratorV4.fulfillIntent.

Before signing, the service checks the payment method, currency, payee, payment time, intent hash, conversion rate and amount. The release amount is:

min(paymentAmount * 10^18 * 10^4 / conversionRate, intentAmount)

paymentAmount is the verified amount in cents of the intent's currency, after any cross-currency adjustment; 10^4 converts cents to 6-decimal USDC units. The signed payload also carries the payment's dispute window. See Unified Payment Verifier for the on-chain format.

Requests carry chainId. The service resolves the UnifiedPaymentVerifierV4 address for that chain itself (0x7bE50E6206a9b3AdF36dbEAFac0e45Cc03A72048 on Base); requests do not include verifyingContract.

Identity registration​

POST /identity proves a live platform account and returns a signed EIP-712 IdentityAttestation. The request includes platform, actionType, callerAddress, encryptedSessionMaterial (a compact JWE to the enclave's upload key that binds the same platform, action and callerAddress) and public params:

PlatformAction typeEncrypted session materialPublic params
venmoregister_venmoCookieSENDER_ID
paypalregister_paypalCookienone
paypalregister_business_paypalCookienone
wiseregister_wiseCookie, X-Access-TokenPROFILE_ID
cashappregister_cashappsessionCookie, requestPayload, optional requestHeadersnone
alipayregister_alipayCookienone

The response contains the normalized identity (platform, actionType, method, payeeId, payeeIdHash, username, metadata), the signed values (method, actionType, callerAddress, payeeIdHash, dataHash, issuedAt, validUntil), signature and signer. Registration APIs consume identity attestations; they are not payment proofs.

A Seller Autopilot credential upload can also return an IdentityAttestation when the encrypted upload includes callerAddress.

Dispute verification​

POST /dispute/verify/venmo/dispute_venmo and POST /dispute/verify/paypal/dispute_paypal accept { encryptedSessionMaterial, params: {}, chainId, intentHash }. Encrypt the complete RFC 5322 dispute email as sessionMaterial: { rawEmail }. The enclave verifies the platform's DKIM signature and extracts the original payment ID, the case ID and the disputed amount.

The response contains a witness signature under the EIP-712 domain { name: "ZKP2P DisputeVerifier", version: "1", chainId, verifyingContract: DisputeVerifier } with type DisputeAttestation(bytes32 intentHash,bytes32 dataHash), plus the encoded dispute details. Build DisputeAttestation { intentHash, dataHash, signatures, data } and submit it to DisputeProtectionPolicyV2.submitDispute (DisputeProtectionPolicy.submitDispute for OrchestratorV3 intents). It is not a payment proof.

@zkp2p/zkp2p-attestation provides createNitroAttestationClient(...).verifyDispute() to encrypt and submit the email, and verifyDisputeAttestation() to check the returned signature and typed data.