This Coinbase Verifications quickstart shows you how to get the metadata associated with a user’s attestation. Our implementation creates a read-only smart contract, to the ensure the integrity of the onchain data.

With a user wallet address and schema ID (a verification type ID), the Coinbase Indexer returns a UID. Then, with the UID, developers can call the EAS SDK to return the metadata associated with the attestation. If there is no attestation created, the Coinbase Indexer returns null.

Prerequisites

  • Node >= 14.0.0
  • npm >= 6.0.0
  • CDP account
  • Base mainnet endpoint

How to get a Base Mainnet Endpoint:

  1. Log into CDP > Node.
  2. Set the dropdown for RPC Endpoint to Base Mainnet.
  3. Copy and save your endpoint to use later.

We use Base mainnet because it is a read-only contract that does not require any gas.

Get Attestation Data

Initialize your project

In your terminal:

  1. Create a directory called attestation-tutorial
  2. Initialize a project using npm.
  3. Download dependencies: eas-sdk and ethers.
mkdir attestation-tutorial & cd attestation-tutorial

npm install @ethereum-attestation-service/eas-sdk

npm install ethers

Set up imported variables

Create a file called indexer.js and add the following variables to import:

const { EAS } = require("@ethereum-attestation-service/eas-sdk");
const { ethers } = require('ethers');

Load and import ABI

  1. Import the ABI file for the Coinbase Indexer contract.
  2. Move the file to the attestation-tutorial directory.
  3. Import the ABI as a variable.
const ABI = require('./attestation_ABI.js');

Create contract instance

Connect to the Base RPC endpoint and create a contract instance:

  1. Copy your endpoint and paste it as the input for the ethers.JsonRpcProvider function.
  2. Input the Coinbase Indexer contract address: 0x2c7eE1E5f416dfF40054c27A62f7B357C4E8619C.
  3. Create the contract instance with contract address, ABI, and provider variables.

Coinbase Indexer contract address: 0x2c7eE1E5f416dfF40054c27A62f7B357C4E8619C

//Set this to the Node RPC URL from Step 1.
const provider = new ethers.JsonRpcProvider("YOUR RPC URL");

const contractAddress = "0x2c7eE1E5f416dfF40054c27A62f7B357C4E8619C";

const indexerContract = new ethers.Contract(contractAddress, ABI, provider);

Get attestation UID

  1. Setup a function that inputs a walletAddress and schemaID to return the attestationUID.

If the attestation does not exist, it returns null.

Fetching Attestation UID

async function getAttestationUID(walletAddress,schemaID) {
    try {
      const attestationUID = await indexerContract.getAttestationUid(walletAddress, schemaID);
      return attestationUID;
    } catch (error) {
      console.error("Error fetching Attestation UID:", error);
    }
  }

Get attestation data

Setup a function that inputs a uid to return attestation:

  1. Input the contract address into EAS.

Fetching Metadata

async function getAttestationData(uid){
  try{
    const EASContractAddress = "0x4200000000000000000000000000000000000021"
    const eas = new EAS(EASContractAddress);
    eas.connect(provider);
    const attestation = await eas.getAttestation(uid);
    return attestation
  } catch(error){
    console.error("Error fetching Metadata: ", error)
  }
}	

Call Functions

  1. Create your main function.
  2. Call the getAttestationUID and getAttestationData functions and input a valid Wallet Address and Schema ID.
  3. Try with the following:
Wallet Address: `0x115aBfDa6b101bDC813B90c2780952E89E185F54`
Schema ID: `0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9

Check out recently claimed wallet addresses, schema IDs, and attestation UIDs we have here:


async function main() {
  // Add any Wallet Address or SchemaID you would like to try.
  const walletAddress = "0x115aBfDa6b101bDC813B90c2780952E89E185F54";
  const schemaID = "0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9";
  try {
      const uid = await getAttestationUID(walletAddress, schemaID);
      console.log('UID:', uid);
      const metadata = await getAttestationData(uid);
      console.log('Metadata:', metadata);
  } catch (error) {
      console.error('Error:', error);
  }
}

main();

Output

You should return the output below. The comments above each line item represent the corresponding variable.

UID: 0x9c2108e7683176078b834068c0a8e6539213a56c3c4ae029d999f69840149911

Metadata: Result(10) [
//uid  '0x9c2108e7683176078b834068c0a8e6539213a56c3c4ae029d999f69840149911',
// schemaID
'0xf8b05c79f090979bf4a80270aba232dff11a10d9ca55c4f88de95317970f0de9',
//time
  1721434067n,
//expirationTime
  0n,
//revocationTime
  0n,
//refUID
'0x0000000000000000000000000000000000000000000000000000000000000000',
//recipient
  '0x115aBfDa6b101bDC813B90c2780952E89E185F54',
//attester
  '0x357458739F90461b99789350868CD7CF330Dd7EE',
//revocable[?]
  true,
//data  
'0x0000000000000000000000000000000000000000000000000000000000000001'
]

ABI File

You can copy the ABI file here, or download coinbase-verifications-abi-code-snippet.json.tar.gz

command to untar
tar -xvf coinbase-verifications-abi-code-snippet.json.tar.gz