# Verifying Zipwire's Merkle Root Attestations for Developers

## Overview

This guide explains how to verify Merkle root attestations issued by Zipwire's master address (see [Zipwire's Master Attester Wallet Address and Public Key](https://docs.zipwire.io/fundamentals/security/attestations/zipwires-master-attester-wallet-address-and-public-key)). Developers can verify these attestations to ensure a wallet holder's identity is trustworthy. This page guides you through validating a user-supplied, signed, and dated Merkle proof document to confirm it matches the attested Merkle root, check the signature, and assess the proof's age.

## Prerequisites

* Familiarity with Ethereum, Merkle trees, and cryptographic signatures.
* Access to Zipwire's master attester details: Zipwire's Master Attester Wallet Address and Public Key (./master-attester).
* Tools: A blockchain explorer (e.g., EAS Scan: <https://base.easscan.org/>) and a library for hash verification (e.g., Web3.js or ethers.js).

## Verification Steps

To trust a Zipwire attestation with a Merkle root hash, follow these steps:

### 1. Obtain the User's Merkle Proof Document

Ask the user to:

* **Sign in with Ethereum**: Prompt the user to authenticate using their Ethereum wallet (via a browser extension or a mobile wallet via WalletConnect) to prove they control the attested wallet address. This involves signing a message (e.g., a nonce or timestamp) using standards like EIP-191 or EIP-712. For smart wallets, verification should follow the EIP-1271 standard.
* **Provide the Merkle Proof Document**: The user submits a Zipwire-signed, dated Merkle proof document, which includes:
  * **Proof Data**: The specific identity attribute (e.g., name or passport number), its hash, and intermediate hashes linking to the Merkle root.
  * **Signature**: A cryptographic signature from Zipwire (using its master attester key) verifying the proof's authenticity.
  * **Date**: The issuance date of the proof to assess its freshness.

### 2. Verify the Merkle Proof

Ensure the proof's hashes match the attested Merkle root:

* Retrieve the Merkle root from the attestation on the Base blockchain using EAS Scan. Search for the user's wallet address and locate the attestation issued by Zipwire's master address (see [Zipwire's Master Attester Wallet Address and Public Key](https://docs.zipwire.io/fundamentals/security/attestations/zipwires-master-attester-wallet-address-and-public-key)).
* Compute the hash of the provided attribute (e.g., SHA-256 of "Alice Smith").
* Use the intermediate hashes in the proof to reconstruct the Merkle root. Libraries like merkletreejs (JavaScript) can automate this.
* Compare the reconstructed root with the on-chain Merkle root. A match confirms the attribute belongs to the attested dataset.

### 3. Validate Zipwire's Signature

* Confirm the proof document's authenticity:
  * Extract the public key from Zipwire's signature using a library like ethers.js.
  * Verify the signature was created by Zipwire's master attester address (see [Zipwire's Master Attester Wallet Address and Public Key](https://docs.zipwire.io/fundamentals/security/attestations/zipwires-master-attester-wallet-address-and-public-key)). For example, use `ethers.verifyMessage(message, signature)` to check the signed proof, ensuring it includes the proof data and date.
  * Confirm the signature matches Zipwire's public key, available at [Zipwire's GitHub](https://github.com/zipwireapp/zipwireapp/blob/master/PUBLICKEYS.md).

### 4. Check the Proof's Date

Assess the proof's age to ensure it's recent:

* Review the date in the proof document. A proof older than your application's threshold (e.g., 30 days) may indicate a stale or compromised wallet.
* Optionally, check the attestation's timestamp on EAS Scan to confirm it aligns with the proof's date.

### 5. Cross-Verify the Attester

Confirm the attestation comes from Zipwire:

* Verify the attester's address matches the official address (see [Zipwire's Master Attester Wallet Address and Public Key](https://docs.zipwire.io/fundamentals/security/attestations/zipwires-master-attester-wallet-address-and-public-key)).
* Cross-check details on Zipwire's GitHub: <https://github.com/zipwireapp/zipwireapp/blob/master/PUBLICKEYS.md>.

## Best Practices

* **Security**: Always validate signatures and hashes to prevent forged proofs.
* **Freshness**: Set a maximum age for proofs (e.g., 7-30 days) based on your use case.
* **Error Handling**: Gracefully handle invalid proofs or mismatches, prompting users to resubmit.
* **Privacy**: Avoid storing sensitive proof data; verify and discard.

## Why It Matters

By verifying Zipwire's Merkle root attestations, developers can trust user identities without compromising privacy, enabling secure dApp interactions, bot prevention, and compliance. For broader verification strategies, see [Holistic Evaluation of Ethereum Wallets](https://docs.zipwire.io/fundamentals/security/wallet-verification-guide/holistic-evaluation-of-ethereum-wallets).
