Hello Humanity Server

In this section you will be creating your first server side integration app with humanity protocol capable of verifying any EIP-55 wallet address against the Humanity Protocol knowledge base through Humanity Protocol API.

You can find the code for this tutorial in the following repo. Remember to rename your .env.example to .env and to add your API key

Let’s first create the folder and basic structure of our project

mkdir hello-humanity-server && cd hello-humanity-server
echo "node_modules \\n .env" >> .gitignore
echo "# hello-humanity-server" >> README.md
git init
touch package.json

Then let’s create our .env file with our HP_API_KEY, our HP_API_URL and the default PORT for our application

HP_API_KEY=<YOUR_HUMANITY_PROTOCOL_API_KEY>
HP_API_URL=https://api.humanity.org
PORT=3002

Create a package.json file at the root of your directory and add the following content

{
  "name": "humanity-protocol-server-example",
  "version": "1.0.0",
  "description": "Server example for Humanity Protocol API",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "start": "node index.js",
    "dev": "node --watch index.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "dotenv": "^16.3.1",
    "node-fetch": "^3.3.2",
    "cors": "^2.8.5",
    "swagger-ui-express": "^5.0.0",
    "swagger-jsdoc": "^6.2.8"
  }
}

Install all the packages with npm i

Now let’s create an index.js file in the root of our directory and import the necessary packages at the top of the file

import express from "express";
import cors from "cors";
import fetch from "node-fetch";
import dotenv from "dotenv";
import swaggerJsdoc from "swagger-jsdoc";
import swaggerUi from "swagger-ui-express";

We will use express to speed up our node.js environment as well cors and node-fetch for cross origin API calls. We will also use swagger to provide docs and a minimal visual implementation to test out our server side application.

Let’s define the behavior and options for our application by including the following code

dotenv.config(); // Use .env variables from our file

// Set Up Express App and Config
const app = express();
const PORT = process.env.PORT || 3002;

//Define the OpenAPI (Swagger) documentation.
const swaggerOptions = {
  definition: {
    openapi: "3.0.0",
    info: {
      title: "Humanity Protocol Server Example",
      version: "1.0.0",
      description:
        "A server example demonstrating integration with Humanity Protocol API",
    },
    servers: [
      {
        url: `http://localhost:${PORT}`,
        description: "Development server",
      },
    ],
  },
  apis: ["./index.js"],
}; // Define swagger options for docs and visualization

const swaggerSpec = swaggerJsdoc(swaggerOptions);

//Middleware Configuration 
app.use(cors());
app.use(express.json());
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));

Bellow our existing code let’s now define our main API endpoint and the corresponding swagger configuration and schemas

/**
 * @swagger
 * components:
 *   schemas:
 *     VerificationResponse:
 *       type: object
 *       properties:
 *         wallet_address:
 *           type: string
 *           description: The wallet address that was verified
 *           example: "0xdead00000000000000000000000000000000beef"
 *         is_human:
 *           type: boolean
 *           description: Whether the wallet is verified as human
 *           example: true
 *         user_id:
 *           type: string
 *           description: The user ID if verified
 *           example: "user_123456"
 *         timestamp:
 *           type: string
 *           format: date-time
 *           description: Timestamp of the verification
 *         server:
 *           type: string
 *           description: Server identifier
 *           example: "humanity-protocol-server-example"
 *     ErrorResponse:
 *       type: object
 *       properties:
 *         error:
 *           type: string
 *           description: Error message
 *         message:
 *           type: string
 *           description: Detailed error message
 *     HealthResponse:
 *       type: object
 *       properties:
 *         status:
 *           type: string
 *           example: "ok"
 *         timestamp:
 *           type: string
 *           format: date-time
 *         apiUrl:
 *           type: string
 *           example: "<https://api.humanity.org>"
 */

/**
 * @swagger
 * /verify/{walletAddress}:
 *   get:
 *     summary: Verify if a wallet address belongs to a human
 *     description: Checks whether the supplied wallet address is associated with a palm-verified Humanity Protocol user
 *     parameters:
 *       - in: path
 *         name: walletAddress
 *         required: true
 *         description: The wallet address to verify (EIP-55 compliant)
 *         schema:
 *           type: string
 *           example: "0xdead00000000000000000000000000000000beef"
 *     responses:
 *       200:
 *         description: Successful verification
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/VerificationResponse'
 *       500:
 *         description: Server error
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/ErrorResponse'
 */
app.get("/verify/:walletAddress", async (req, res) => {
  const { walletAddress } = req.params; // get params from URL

  console.log(
    `[${new Date().toISOString()}] Verifying wallet: ${walletAddress}`,
  ); // Outpout timestamp

  if (!process.env.HP_API_URL) {
    console.error("HP_API_URL is not set in environment variables");
    return res.status(500).json({
      error: "Server configuration error",
      message: "API URL not configured. Please check your .env file.",
    });
  } // Check for properly configured HP_API_URL

  if (!process.env.HP_API_KEY) {
    console.error("HP_API_KEY is not set in environment variables");
    return res.status(500).json({
      error: "Server configuration error",
      message: "API key not configured. Please check your .env file.",
    });
  } // Check for properly configured HP_API_KEY

  try {
    const apiUrl = `${process.env.HP_API_URL}/v1/human/verify?wallet_address=${walletAddress}`; // Define our end point URL
    console.log(`[${new Date().toISOString()}] Making request to: ${apiUrl}`); // Log the call

    const response = await fetch(apiUrl, {
      headers: {
        "X-HP-API-Key": process.env.HP_API_KEY,
      },
    }); // Do the fetching to Humanity Protocol API

    const data = await response.json(); // Await response

    console.log(`[${new Date().toISOString()}] Response:`, data); // Log results

    if (!response.ok) {
      return res.status(response.status).json({
        ...data,
        timestamp: new Date().toISOString(),
        server: "humanity-protocol-server-example",
      });
    } // check unsuccessful responses from the Humanity Protocol API

    res.json({
      ...data,
      timestamp: new Date().toISOString(),
      server: "humanity-protocol-server-example",
    }); // Generate app response
  } catch (error) {
    console.error(`[${new Date().toISOString()}] Error:`, error);
    res.status(500).json({
      error: "Failed to verify wallet",
      message: error.message,
    });
  } // Catch JavaScript-level or network-level errors
});

And our health check to verify the server is up and knows where the API is

/**
 * @swagger
 * /health:
 *   get:
 *     summary: Check server health
 *     description: Returns the current server status and configuration
 *     responses:
 *       200:
 *         description: Server is healthy
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/HealthResponse'
 */
app.get("/health", (req, res) => {
  res.json({
    status: "ok",
    timestamp: new Date().toISOString(),
    apiUrl: process.env.HP_API_URL,
  });
});

Finally let’s start the server with our PORT and HP_API_URL

app.listen(PORT, () => {
  console.log(`Server running on <http://localhost>:${PORT}`);
  console.log(`Swagger docs available at <http://localhost>:${PORT}/api-docs`);
  console.log(`Using Humanity Protocol API at: ${process.env.HP_API_URL}`);
});

Your index.js file should like this this

import express from "express";
import cors from "cors";
import fetch from "node-fetch";
import dotenv from "dotenv";
import swaggerJsdoc from "swagger-jsdoc";
import swaggerUi from "swagger-ui-express";

dotenv.config();

const app = express();
const PORT = process.env.PORT || 3002;

const swaggerOptions = {
  definition: {
    openapi: "3.0.0",
    info: {
      title: "Humanity Protocol Server Example",
      version: "1.0.0",
      description:
        "A server example demonstrating integration with Humanity Protocol API",
    },
    servers: [
      {
        url: `http://localhost:${PORT}`,
        description: "Development server",
      },
    ],
  },
  apis: ["./index.js"],
};

const swaggerSpec = swaggerJsdoc(swaggerOptions);

app.use(cors());
app.use(express.json());
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));

/**
 * @swagger
 * components:
 *   schemas:
 *     VerificationResponse:
 *       type: object
 *       properties:
 *         wallet_address:
 *           type: string
 *           description: The wallet address that was verified
 *           example: "0xdead00000000000000000000000000000000beef"
 *         is_human:
 *           type: boolean
 *           description: Whether the wallet is verified as human
 *           example: true
 *         user_id:
 *           type: string
 *           description: The user ID if verified
 *           example: "user_123456"
 *         timestamp:
 *           type: string
 *           format: date-time
 *           description: Timestamp of the verification
 *         server:
 *           type: string
 *           description: Server identifier
 *           example: "humanity-protocol-server-example"
 *     ErrorResponse:
 *       type: object
 *       properties:
 *         error:
 *           type: string
 *           description: Error message
 *         message:
 *           type: string
 *           description: Detailed error message
 *     HealthResponse:
 *       type: object
 *       properties:
 *         status:
 *           type: string
 *           example: "ok"
 *         timestamp:
 *           type: string
 *           format: date-time
 *         apiUrl:
 *           type: string
 *           example: "<https://api.humanity.org>"
 */

/**
 * @swagger
 * /verify/{walletAddress}:
 *   get:
 *     summary: Verify if a wallet address belongs to a human
 *     description: Checks whether the supplied wallet address is associated with a palm-verified Humanity Protocol user
 *     parameters:
 *       - in: path
 *         name: walletAddress
 *         required: true
 *         description: The wallet address to verify (EIP-55 compliant)
 *         schema:
 *           type: string
 *           example: "0xdead00000000000000000000000000000000beef"
 *     responses:
 *       200:
 *         description: Successful verification
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/VerificationResponse'
 *       500:
 *         description: Server error
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/ErrorResponse'
 */
app.get("/verify/:walletAddress", async (req, res) => {
  const { walletAddress } = req.params;

  console.log(
    `[${new Date().toISOString()}] Verifying wallet: ${walletAddress}`,
  );

  if (!process.env.HP_API_URL) {
    console.error("HP_API_URL is not set in environment variables");
    return res.status(500).json({
      error: "Server configuration error",
      message: "API URL not configured. Please check your .env file.",
    });
  }

  if (!process.env.HP_API_KEY) {
    console.error("HP_API_KEY is not set in environment variables");
    return res.status(500).json({
      error: "Server configuration error",
      message: "API key not configured. Please check your .env file.",
    });
  }

  try {
    const apiUrl = `${process.env.HP_API_URL}/v1/human/verify?wallet_address=${walletAddress}`;
    console.log(`[${new Date().toISOString()}] Making request to: ${apiUrl}`);

    const response = await fetch(apiUrl, {
      headers: {
        "X-HP-API-Key": process.env.HP_API_KEY,
      },
    });

    const data = await response.json();

    console.log(`[${new Date().toISOString()}] Response:`, data);

    if (!response.ok) {
      return res.status(response.status).json({
        ...data,
        timestamp: new Date().toISOString(),
        server: "humanity-protocol-server-example",
      });
    }

    res.json({
      ...data,
      timestamp: new Date().toISOString(),
      server: "humanity-protocol-server-example",
    });
  } catch (error) {
    console.error(`[${new Date().toISOString()}] Error:`, error);
    res.status(500).json({
      error: "Failed to verify wallet",
      message: error.message,
    });
  }
});

/**
 * @swagger
 * /health:
 *   get:
 *     summary: Check server health
 *     description: Returns the current server status and configuration
 *     responses:
 *       200:
 *         description: Server is healthy
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/HealthResponse'
 */
app.get("/health", (req, res) => {
  res.json({
    status: "ok",
    timestamp: new Date().toISOString(),
    apiUrl: process.env.HP_API_URL,
  });
});

app.listen(PORT, () => {
  console.log(`Server running on <http://localhost>:${PORT}`);
  console.log(`Swagger docs available at <http://localhost>:${PORT}/api-docs`);
  console.log(`Using Humanity Protocol API at: ${process.env.HP_API_URL}`);
});

Go ahead and fire up the application by running npm run dev in your terminal. You should see something like this

> [email protected] dev
> node --watch index.js

Server running on <http://localhost:3002>
Swagger docs available at <http://localhost:3002/api-docs>
Using Humanity Protocol API at: <https://api.humanity.org>

You can now start testing your application in your browser by going to http://localhost:3002 annd adding any wallet address as param for the call to the /verify/ endpoint. Example:

http://localhost:3002/verify/<WALLET_ADDRESS>

You also have an UI via swagger by visiting http://localhost:3002/api-docs where you should the following screen.

To make a call to our /verify end point, expand the /verify/{walletAddress} option and click on Try it out

Change the default wallet address to any EIP-55 compliant address and click Execute

A new block under response will appear showing you the results of the call to Humanity Protocol API with response types and logs whether for successful or unsuccessful responses.

Congratulations, you have build your own API service connected to Humanity Protocol capable of validating any EIP-55 wallet address. Feel free to modify or expand this implementation to integrate your own service.

Next Steps

If you want to explore a client side integration to integrate your project into humanity protocol please visit our hello humanity client

You are now equipped to develop more sophisticated applications and incorporate Humanity Protocol into your existing systems. To facilitate this process, please visit our Developers Portal where you can access comprehensive resources to create innovative applications that ensure each user is a verified unique individual.

Last updated