Authento API
  • Welcome to Authento
  • Integration Guidance
    • Introduction
    • Address-Based Verification
      • Off-Chain Access Control
      • On-Chain Access Control
        • Digital Signature Verification
        • Merkel Proof Verification
    • Account-Based Verification
    • Webhooks
  • API Reference
    • General Information
    • Endpoints
      • Get Basic User Info
      • Get Full User Info
  • Authento-react
    • Getting Started
    • useSignature
    • useStatus
    • useTokenVerifyPopup
    • useVerifyPopup
Powered by GitBook
On this page
  • Steps
  • Backend
  • Frontend
  • Authento-react (recommended)
  • Manual integration
  • Webhooks Handling
  • Examples
  1. Integration Guidance
  2. Address-Based Verification

Off-Chain Access Control

PreviousAddress-Based VerificationNextOn-Chain Access Control

Last updated 1 year ago

To restrict access to specific features or functionalities on your website based on the KYC/AML status of the user, you need to implement off-chain access control.

Steps

  1. [Backend] Configure the server to request and handle KYC/AML data from Authento.

  2. [Frontend] Implement access control based on the status response returned from your backend.

  3. [Backend] (Optional) Set up handlers for verification webhooks.

Backend

You have to set up a server which requests and handles KYC/AML data from Authento. The exact implementation depends on your use case. For example, you could configure your server to

  • Request KYC/AML status by wallet address upon user sign-in.

  • Confirm KYC/AML status when a user makes a withdrawal request.

Once the KYC/AML status is retrieved, it should be processed on your backend to derive the permissions which should be granted to the user.

The API response from Authento contains sensitive information and should NOT be directly relayed to the end user.

Instead, the API response should be used to derive user permissions server-side, and only such permissions should be sent back to the client.

Backend examples

const crypto = require("crypto");
const express = require("express");

const app = express();

// TODO: Configure your Authento settings
const apiKey = "YOUR_API_KEY";
const apiSecret = "YOUR_API_SECRET";
const basicUserInfoEndpoint = "https://api.authento.io/userinfo/basic";

/**
 * Returns the KYC status of an address retrieved using Authento API
 * @api {get} /userinfo/basic?address=:address
 * @apiParam {String} address EVM compatible address
 * @apiSuccess 
 *   {String="unverified","processing","info_required",verified","rejected"}
 *   status KYC status of the address
 * @apiError {String} detail Error detail
 */
app.get("/userinfo/basic", async (req, res) => {
  try {
    const address = req.query.address;

    if (!address) {
      throw new Error("Invalid address");
    }

    const url = `${basicUserInfoEndpoint}?address=${address}`;
    const timestamp = Date.now();
    const signature = crypto
      .createHmac("sha256", apiSecret)
      .update(`${timestamp}GET${url}`)
      .digest("hex");

    const { status, type } = await fetch(url, {
      headers: {
        "X-AUTHENTO-APIKEY": apiKey,
        "X-AUTHENTO-SIGNATURE": signature,
        "X-AUTHENTO-TS": timestamp,
      },
    })
      .then((response) => response.json())
      .then((data) => data.result);

    // TODO: Implement additional filters based on user attributes such
    //  as nationality/age/pep/riskScore as needed.
    //  Fields other than 'status' should NOT be included
    //  in the response as they might contain sensitive information.
    res.json({ status, type });
  } catch {
    res.status(400).json({ detail: "Failed to retrieve basic user info" });
  }
});

app.listen(3000, () => {
  console.log("Server listening on port 3000");
});
import time
import hmac
import requests
from fastapi import FastAPI, HTTPException

app = FastAPI()

# TODO: Configure your Authento settings
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
ENDPOINT = "https://api.authento.io/userinfo/basic"


@app.get("/userinfo/basic")
async def get_basic_userinfo(address: str):
    """
    Returns the KYC status of an address retrieved using Authento API
    @api {get} /userinfo/basic?address=:address
    @apiParam {String} address EVM compatible address
    @apiSuccess 
        {String="unverified","processing","info_required",verified","rejected"}
        status KYC status of the address
    @apiError {String} detail Error detail
    """
    try:
        timestamp = int(time.time() * 1000)
        payload = f'{timestamp}GET{ENDPOINT}?address={address}'.encode()
        signature = hmac.new(API_SECRET.encode(), payload,
                             'sha256').hexdigest()
        headers = {
            "X-AUTHENTO-APIKEY": API_KEY,
            "X-AUTHENTO-SIGNATURE": signature,
            "X-AUTHENTO-TS": str(timestamp),
        }
        params = {
            "address": address
        }
        response = requests.get(ENDPOINT, headers=headers, params=params)
        user_data = response.json()
        # TODO: Implement additional filters based on user attributes such as
        #  nationality/age/pep/riskScore as needed.
        #  Fields other than 'status' should NOT be included
        #  in the response as they might contain sensitive information.
        return {
            "status": user_data['result']['status'],
            "type": user_data['result']['type']
        }
    except:
        raise HTTPException(
            status_code=400, detail="Failed to retrieve basic user info")

Frontend

Aside from restricting user access based on KYC status returned from your backend, your frontend should be set up to initialize Authento KYC on users' demand. You can do this using the authento-react package, or you can do this manually.

Authento-react (recommended)

Manual integration

Take the following steps to initialize the Authento verification process manually:

  1. Create a signature for the following typed structured data:

    const domain = { name: YOUR_DOMAIN_NAME };
    const types = {
      Message: [
        { name: "content", type: "string" },
        { name: "for", type: "string" },
        { name: "timestamp", type: "string" },
        { name: "nonce", type: "string" },
      ],
    };
    const primaryType = "Message";
    const message = {
      content:
        "Sign this message to prove your ownership of this address " +
        "and proceed with the identity verification process.",
      for: domainName,
      timestamp: CURRENT_TIMESTAMP,
      nonce: NONCE,
    };
    • YOUR_DOMAIN_NAME: Your domain name registered with Authento. Please contact us if you are unsure of its value.

    • CURRENT_TIMESTAMP: The number of milliseconds elapsed since the Unix epoch as a string.

    • NONCE: Randomly generated string as a safeguard against replay attacks. You can use uuid or other packages to generate this.

    const signature = await signTypedData({
      domain,
      message,
      primaryType,
      types,
    })

Remember to refresh CURRENT_TIMESTAMP and NONCE just before the signature is generated.

  1. Upon successful generation of the signature, direct the user to https://www.authento.io/verify/${YOUR_DOMAIN_NAME} using a modal or a popup with the following query parameters:

    • address: The EVM address to verify

    • ts: CURRENT_TIMESTAMP as defined above

    • nonce: NONCE as defined above

    • signature: The signature generated

    • levelType: "BASIC" or "POA"

The signature generated will be verified on Authento server to ensure the user's ownership of the address. There's no need to worry about malicious users attempting to register addresses for which they do not own the private key

  1. Users will then proceed with the verification process on the newly opened modal or popup.

Webhooks Handling

Examples

Generate an API key/secret pair from the under the Settings tab

For details on how KYC/AML status can be retrieved using the Authento API, please refer to the section.

This package contains custom react hooks which makes it very simple to integrate Authento into your platform. For detailed instructions or usage examples, please refer to .

On the library, the signature can be generated as follows:

In address-based verification, you are not assumed to be managing your own user database. In case you do, however, you can ensure that your user data is up to date by setting up an endpoint to handle and process webhooks data. For more information on webhooks, please refer to.

Authento Dashboard
endpoints
this section
Wagmi
this section
Node.js backend
Python.js backend
React/Next.js frontend + backend
User verification flow