Off-Chain Access Control
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
Generate an API key/secret pair from the Authento Dashboard under the Settings tab
[Backend] Configure the server to request and handle KYC/AML data from Authento.
[Frontend] Implement access control based on the status response returned from your backend.
[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.
For details on how KYC/AML status can be retrieved using the Authento API, please refer to the endpoints section.
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");
});
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)
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 this section.
Manual integration
Take the following steps to initialize the Authento verification process manually:
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.
On the Wagmi library, the signature can be generated as follows:
const signature = await signTypedData({ domain, message, primaryType, types, })
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 verifyts
: CURRENT_TIMESTAMP as defined abovenonce
: NONCE as defined abovesignature
: The signature generatedlevelType
: "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
Users will then proceed with the verification process on the newly opened modal or popup.
Webhooks Handling
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 this section.
Examples
Last updated