Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up a Cross-Chain KYC/AML Compliance Portal

A technical tutorial for developers to build a compliance portal that verifies user identity once and whitelists their addresses across multiple blockchains for fundraising events.
Chainscore © 2026
introduction
DEVELOPER GUIDE

Setting Up a Cross-Chain KYC/AML Compliance Portal

A technical guide to building a compliance portal that verifies user identity and screens transactions across multiple blockchains.

A cross-chain compliance portal is a critical infrastructure component for regulated DeFi applications. It centralizes user identity verification (KYC) and transaction monitoring (AML) across multiple blockchain networks like Ethereum, Polygon, and Solana. Unlike traditional finance where compliance is siloed per institution, a cross-chain portal must handle fragmented user addresses, varying transaction formats, and different smart contract standards. The core challenge is creating a unified identity layer that persists across chains, linking a user's verified identity to all their wallet addresses and monitoring their aggregate activity for risk.

The system architecture typically involves three key components: an off-chain verification service, an on-chain identity registry, and a cross-chain message relayer. The off-chain service handles the sensitive KYC process, often using providers like Synaps, Persona, or a custom solution. Once verified, a user's identity is cryptographically attested to and linked to a primary wallet. This attestation—often a signed message or a verifiable credential—is then recorded in an on-chain identity registry smart contract. This contract becomes the source of truth for a user's verified status, which other dApps can permissionlessly query.

To extend compliance across chains, you need a mechanism to synchronize the verified identity state. This is where a cross-chain message relayer like Axelar, LayerZero, or Wormhole comes in. When a user's status is updated on the "home" chain (e.g., Ethereum), the relayer passes a signed message to a mirror identity registry on a destination chain (e.g., Avalanche). The receiving contract verifies the message's origin and updates its local state. This ensures a user only needs to complete KYC once, and their verified status is recognized on all connected networks, enabling seamless but compliant cross-chain interactions.

For transaction screening (AML), the portal must monitor on-chain activity. This involves indexing transactions from multiple chains via RPC nodes or subgraphs and feeding them into a risk engine. Services like Chainalysis, TRM Labs, or open-source tools like tornado-cash-tracker can screen addresses and transactions against sanctions lists and known illicit activity patterns. Alerts for high-risk transactions can trigger automated actions via smart contracts, such as pausing withdrawals or flagging the activity for manual review by a compliance officer.

Here is a simplified code example for an identity registry contract that stores verification status and allows cross-chain updates via a trusted relayer:

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract CrossChainIdentityRegistry {
    address public admin;
    address public trustedRelayer; // e.g., Axelar Gateway address
    
    // Maps user address to verification status and timestamp
    mapping(address => bool) public isVerified;
    mapping(address => uint256) public verifiedAt;

    event UserVerified(address indexed user, uint256 timestamp);
    event StatusUpdatedViaRelayer(address indexed user, bool status, uint256 timestamp, uint256 srcChainId);

    constructor(address _trustedRelayer) {
        admin = msg.sender;
        trustedRelayer = _trustedRelayer;
    }

    // Called by off-chain KYC service
    function verifyUser(address _user) external onlyAdmin {
        isVerified[_user] = true;
        verifiedAt[_user] = block.timestamp;
        emit UserVerified(_user, block.timestamp);
    }

    // Called by the cross-chain relayer contract
    function updateStatusFromRelayer(address _user, bool _status, uint256 _srcChainId, bytes calldata _signature) external {
        require(msg.sender == trustedRelayer, "Untrusted relayer");
        // Verify signature from source chain's admin here
        isVerified[_user] = _status;
        verifiedAt[_user] = block.timestamp;
        emit StatusUpdatedViaRelayer(_user, _status, block.timestamp, _srcChainId);
    }

    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }
}

When implementing a production system, key considerations include data privacy (storing minimal personal data on-chain), user experience (streamlining the verification flow), and regulatory alignment (ensuring the system meets specific jurisdictional requirements like FATF's Travel Rule). The portal should be designed as modular services, allowing you to swap out verification providers or relayer networks as needed. By building a robust cross-chain compliance layer, developers can unlock access to institutional capital and build DeFi applications that operate within global regulatory frameworks while preserving the core benefits of blockchain interoperability.

prerequisites
FOUNDATION

Prerequisites and System Architecture

A cross-chain KYC/AML portal requires a robust technical foundation. This section outlines the essential components, from smart contract infrastructure to data oracles, needed to build a compliant and functional system.

Before writing any code, you must define the system's core architecture. A typical portal consists of three main layers: the on-chain verification layer (smart contracts), the off-chain compliance engine (backend services), and the user interface (frontend dApp). The on-chain layer manages identity attestations and status flags, the off-chain engine performs risk analysis and document checks, and the frontend provides the user onboarding flow. This separation ensures that sensitive PII (Personally Identifiable Information) is processed off-chain while only verification results are stored on-chain.

The primary prerequisite is selecting the blockchains your portal will support. Start with EVM-compatible chains like Ethereum, Polygon, and Arbitrum for their extensive tooling and user base. For each chain, you'll need to deploy a set of core smart contracts. The key contract is a KYCRegistry, which maps user addresses (e.g., 0x...) to a verification status and a unique, off-chain identifier. Use a proxy upgrade pattern (like OpenZeppelin's) for these contracts to allow for future compliance rule updates without requiring users to re-verify.

Your off-chain backend requires a secure, scalable environment. You'll need a server (or serverless functions) to run a compliance engine that integrates with third-party KYC providers like Sumsub or Jumio. This engine receives user-submitted data, calls the provider's API, processes the result, and submits a transaction to update the KYCRegistry. Crucially, this server must sign transactions with a dedicated operator wallet, whose private key must be secured using a service like AWS KMS, GCP Secret Manager, or a dedicated custody solution.

To make on-chain status checks gas-efficient for other dApps, implement a verification oracle. Instead of requiring dApps to read your contract on every chain, you can use a cross-chain messaging protocol like Chainlink CCIP or Axelar to relay verification states to a central, cost-efficient chain (e.g., Polygon). A dApp on any connected chain can then query this single source of truth. Alternatively, use a decentralized identifier (DID) standard like ERC-725 or Verifiable Credentials to give users control over their attestations, which they can present across chains.

Finally, consider data storage and privacy. User documents and detailed profiles should never be stored on-chain. Use encrypted off-chain storage with access controls. Solutions like IPFS with Lit Protocol for encryption, Ceramic Network for mutable data streams, or traditional encrypted databases are appropriate. Your architecture must be designed for selective disclosure, allowing users to prove specific claims (e.g., "is over 18") without revealing their full identity document, potentially using zero-knowledge proofs (ZKPs) in future iterations.

key-concepts-text
CORE CONCEPTS: VERIFIABLE CREDENTIALS AND ATTESTATIONS

Setting Up a Cross-Chain KYC/AML Compliance Portal

A technical guide to building a decentralized identity verification system that works across multiple blockchains using verifiable credentials and on-chain attestations.

A cross-chain KYC/AML portal allows users to complete identity verification once and use the resulting attestation across multiple blockchain ecosystems. This solves a critical pain point where users must repeat the same KYC process for each new DeFi protocol or chain, which is inefficient and compromises privacy. The core components are a verifiable credential (VC) issued by a trusted entity and an on-chain attestation that serves as a portable, privacy-preserving proof. The VC is a W3C-standard digital document containing verified claims (like a government ID check), while the attestation is its corresponding on-chain record, often using standards like EAS (Ethereum Attestation Service) or Verax.

The system architecture typically involves three layers. The issuer layer consists of accredited KYC providers (like Fractal ID or Civic) that perform the verification and issue a signed VC to the user's digital wallet. The attestation layer uses a service like EAS to create a corresponding on-chain record, which can be a hash of the VC or a zero-knowledge proof to preserve privacy. Finally, the verifier layer includes smart contracts on various chains (Ethereum, Polygon, Arbitrum) that can check the attestation's validity via cross-chain messaging protocols like LayerZero or Axelar before granting access.

To implement this, you first need to integrate a KYC provider's API. For example, using Fractal ID, you would redirect users to their verification flow and receive a callback with a signed JWT credential. This credential contains claims like "kycStatus": "approved" and "countryCode": "US". You must validate the issuer's signature against their public key, which is often published on a decentralized registry like the DID (Decentralized Identifier) method did:web or did:key. Store only the essential minimum data required for compliance on-chain.

Next, create the on-chain attestation. Using the Ethereum Attestation Service (EAS) on Ethereum Sepolia as an example, you would call the attest function on the EAS contract. The attestation data field should contain a hash of the VC or a zk-SNARK proof, not the raw PII. For cross-chain functionality, you then use a cross-chain messaging protocol. With LayerZero, you would send the attestation's unique identifier (like its uid) from the source chain to a destination chain, where a verifier contract can validate the message's origin and check the attestation's status via a lightweight client.

A critical consideration is privacy and data minimization. Instead of attesting to raw data like a user's name, attest to a zero-knowledge proof generated from the VC using a zk-circuit (e.g., with Circom). This allows the verifier contract to confirm the user is from an approved jurisdiction and has a valid KYC status without exposing the underlying data. Frameworks like Sismo or Semaphore can facilitate this. Always ensure your design complies with regulations like GDPR by keeping personal data off-chain and giving users control over their credentials.

In practice, your portal's frontend would guide the user through the KYC flow, manage their wallet connection, and pay for attestation gas fees. The backend service handles API calls to the KYC issuer and submits the attestation transaction. For developers, the key tools are EAS SDK, LayerZero SDK, and wallet libraries like wagmi. Testing should be done on testnets with mock KYC providers. This architecture creates a reusable, user-centric compliance layer that reduces friction in the multi-chain ecosystem while upholding security and regulatory standards.

system-components
CROSS-CHAIN COMPLIANCE

System Components and Tools

Essential tools and frameworks for building a secure, interoperable KYC/AML portal that works across multiple blockchain networks.

step-1-integrate-kyc-provider
FOUNDATION

Step 1: Integrate a KYC/AML Provider

The first step in building a compliant cross-chain portal is integrating a specialized KYC/AML provider. This establishes the legal and technical foundation for user onboarding.

A Know Your Customer (KYC) and Anti-Money Laundering (AML) provider is a third-party service that verifies user identities and screens them against global sanctions lists and watchlists. For a cross-chain portal, this is non-negotiable. It ensures you comply with regulations like the Travel Rule (FATF Recommendation 16) and mitigates the risk of processing transactions for sanctioned entities. Leading providers include Sumsub, Veriff, Jumio, and Onfido, each offering APIs tailored for crypto and DeFi applications.

Integration typically involves implementing a provider's Software Development Kit (SDK) or REST API. The core workflow is: 1) Your portal redirects a user to the provider's hosted verification flow, 2) The user submits identity documents (passport, driver's license) and may complete a liveness check, 3) The provider returns a verification status and a unique user ID. You must securely store this ID on-chain or in your backend to link the user's wallet address to their verified identity. Most providers offer webhooks to receive real-time status updates.

For a technical implementation, you would first install the provider's SDK (e.g., npm install @sumsub/react-native-sdk). Then, initialize it with your accessToken and applicantId. The code snippet below shows a basic React component triggering the verification flow:

javascript
import { SumsubWebSdk } from '@sumsub/websdk-react';

function KYCComponent() {
  const accessToken = await fetchAccessToken(userId); // Fetch from your backend
  return (
    <SumsubWebSdk
      accessToken={accessToken}
      expirationHandler={() => {/* Renew token */}}
      onMessage={(type, payload) => {
        console.log('Verification Event:', type); // e.g., 'idCheck.onApplicantStatusChanged'
      }}
    />
  );
}

Critical considerations for cross-chain use include provider coverage and data persistence. Ensure your chosen provider supports the jurisdictions of your target users. Furthermore, since users may interact from multiple wallet addresses across different chains, your system must correctly associate all addresses with a single, verified identity record. This often requires a backend mapping table linking the provider's applicantId to an array of walletAddresses. Failure to do this creates compliance gaps.

Finally, integrate the verification result into your portal's logic. A common pattern is to mint a Soulbound Token (SBT) or set a status flag in a smart contract upon successful KYC. This on-chain record can then be permissionlessly checked by your bridge or swap contracts before allowing transactions. For example, a contract might include a modifier like modifier onlyKYCed(address user) { require(kycRegistry.isVerified(user), "Not KYC"); _; }. This creates a transparent, auditable compliance layer.

step-2-issue-verifiable-credential
CREDENTIAL MANAGEMENT

Step 2: Issue and Store a Verifiable Credential

This step details the technical process of issuing a KYC/AML credential as a Verifiable Credential (VC) and storing its hash on-chain for verification.

A Verifiable Credential (VC) is a W3C standard for tamper-evident digital credentials. For KYC, this is a JSON-LD or JWT document containing verified user attributes (e.g., name, country, accreditation status) and cryptographic proof from the issuer. The credential itself is stored off-chain, typically in the user's digital wallet or a secure issuer database, to preserve user privacy and data sovereignty. Only a cryptographic hash of the credential is stored on-chain, creating a public, immutable proof of issuance without exposing the underlying personal data.

To issue a credential, you use a VC issuance library like didkit, veramo, or ssi-sdk. The process involves signing the credential data with the issuer's Decentralized Identifier (DID) private key. Here is a simplified example using a hypothetical SDK:

javascript
const credential = await sdk.createCredential({
  issuer: 'did:ethr:0x123...',
  subject: 'did:ethr:0x456...',
  claims: {
    'KYCStatus': 'Approved',
    'countryOfResidence': 'US',
    'accreditedInvestor': true
  },
  expirationDate: '2025-12-31'
});
const vcJwt = await sdk.signCredential(credential, issuerPrivateKey);

The resulting signed VC (in JWT format) is delivered to the user's wallet.

The critical step for cross-chain verification is anchoring the credential's hash on-chain. Compute a hash (e.g., keccak256) of the signed VC and record it in a smart contract on a base layer like Ethereum or a dedicated L2 (e.g., Base, Arbitrum). This contract acts as a public registry. Storing just the hash minimizes on-chain gas costs and keeps personal data private. Any verifier on any connected chain can later query this registry to confirm a credential's validity by comparing hashes, enabling trustless, cross-chain KYC status checks.

step-4-deploy-whitelist-contracts
IMPLEMENTATION

Step 4: Deploy Whitelist Manager Contracts

This step involves deploying the core smart contracts that will manage the whitelist of verified users across different blockchains.

The Whitelist Manager is the central on-chain registry for your compliance portal. It stores the mapping between user wallet addresses and their verification status. For a cross-chain system, you typically need two types of contracts: a main manager on a primary chain (like Ethereum or Polygon) and light client or bridge contracts on each supported destination chain (like Arbitrum, Optimism, or BNB Chain). The main contract holds the canonical list, while the peripheral contracts receive state updates via a trusted cross-chain messaging protocol like Axelar, LayerZero, or Wormhole.

Start by deploying the main WhitelistManager.sol contract. This contract should have functions to addToWhitelist(address _user, bytes32 _proof) and removeFromWhitelist(address _user), which are callable only by a designated admin or a verifier contract. It must also emit events for each update, as these events are crucial for cross-chain communication. Store verification data efficiently using mappings, and consider using merkle trees for gas-efficient proof verification if you need to validate membership without exposing the full list on a destination chain.

Next, deploy the destination chain adapter contracts. For each chain you wish to support, deploy a simple contract that can receive messages from your chosen cross-chain bridge. This contract needs a function, often called by the bridge's relayer, to update a local mapping based on instructions from the main manager. For example, using Axelar, your DestinationWhitelist.sol would implement the IAxelarExecutable interface to execute the whitelist update upon receiving a verified message.

After deployment, you must link the contracts via the bridge network. This involves configuring the main manager to send messages through the bridge's gateway when the whitelist changes. You will need to fund the main contract with the bridge's native gas token to pay for cross-chain message fees. Test this flow thoroughly on testnets: add an address on the main chain and verify it appears correctly on the destination chain contract within a few blocks.

Finally, verify and publish your contract source code on block explorers like Etherscan or Polygonscan. This is critical for transparency and security, allowing users and auditors to verify the contract logic. Ensure you set up proper access controls, pausing mechanisms, and a clear upgrade path (using proxies like OpenZeppelin's TransparentUpgradeableProxy) to manage the system post-deployment. Your contracts are now the foundational layer for your cross-chain KYC/AML portal.

ARCHITECTURE COMPARISON

On-Chain vs Off-Chain Attestation Storage

A technical comparison of storage strategies for KYC/AML attestation data in a cross-chain compliance portal.

Feature / MetricOn-Chain StorageOff-Chain Storage (IPFS/Arweave)Hybrid Storage (EAS)

Data Immutability & Integrity

Public Data Accessibility

Configurable

Storage Cost per Attestation

$5-15 (Ethereum)

$0.01-0.10

$0.50-2.00 + gas

Data Update/Revocation

Complex (new TX)

Simple (new CID)

Native support

Query Speed & Latency

~3-15 sec (block time)

< 1 sec (gateway cache)

~3-15 sec (on-chain ref)

Cross-Chain Verification Complexity

High (requires bridge/messaging)

Low (CID is universal)

Medium (on-chain schema reg)

Regulatory Data Privacy (GDPR)

Partial (off-chain payload)

Long-Term Data Persistence Guarantee

As long as chain exists

Depends on pinning service

Depends on off-chain layer

step-5-frontend-integration
FRONTEND DEVELOPMENT

Step 5: Build the Contributor Frontend Portal

This step focuses on building the user-facing interface where contributors can initiate and manage their cross-chain KYC/AML verification process.

The frontend portal is the primary interface for users to interact with your compliance system. Its core function is to securely collect user data, initiate verification checks across different blockchains, and display the resulting attestations. You should build this using a modern web framework like React or Vue.js, connecting to the backend API you built in the previous step. Key pages include a dashboard, a KYC submission form, and a status tracker for on-chain attestations. Ensure the UI clearly communicates the multi-step process: data submission, off-chain verification, and on-chain proof generation.

User authentication is critical. Implement a wallet connection using libraries like wagmi (for EVM chains) or @solana/wallet-adapter to allow users to sign in with their Web3 wallets (e.g., MetaMask, Phantom). This wallet address becomes the user's primary identifier across chains. The portal must then guide the user through submitting their KYC information, which typically includes uploading a government-issued ID and a selfie for liveness checks. All sensitive data should be transmitted directly to your secure backend API, never stored or logged in the frontend code.

After submission, the portal must poll your backend API or listen for webhook events to update the user on their verification status. Once the off-chain checks are complete and an attestation is minted, the frontend needs to fetch and display this proof. Use blockchain explorers (like Etherscan or Solana Explorer) and attestation registry viewers (like EAS Explorer) to create direct links to the on-chain attestation, providing transparency. The UI should also handle the scenario where a user wants to use their attestation on another chain, triggering the cross-chain relay process via your backend.

For a production-ready application, focus on security and user experience. Implement rate limiting on form submissions, use HTTPS exclusively, and consider adding a Content Security Policy (CSP). The design should be clear and guide non-technical users through a potentially complex process. Provide tooltips explaining why certain data is needed and what happens to it. Testing is essential: conduct thorough tests with testnet attestations (e.g., on Sepolia or Solana Devnet) and simulated user journeys to ensure all flows—submission, status updates, and cross-chain proof retrieval—work seamlessly.

DEVELOPER FAQ

Frequently Asked Questions

Common technical questions and troubleshooting for building a cross-chain KYC/AML portal using Chainscore's infrastructure.

A cross-chain KYC/AML portal is a unified interface that allows users to complete a single identity verification (KYC) and risk screening (AML) process, and then use that verified status across multiple blockchain networks. It works by leveraging a decentralized identity standard like Verifiable Credentials (VCs) or Soulbound Tokens (SBTs).

Here's the typical flow:

  1. A user submits documents via your portal's frontend.
  2. Your backend uses Chainscore's API to perform checks (e.g., OFAC sanctions, PEP screening).
  3. Upon approval, a cryptographically signed credential is issued to the user's wallet.
  4. This credential can be presented to smart contracts on supported chains (e.g., Ethereum, Polygon, Arbitrum) to access gated services, without repeating the KYC process.

The portal manages the issuance, revocation, and on-chain verification of these credentials across ecosystems.

How to Build a Cross-Chain KYC/AML Portal for Fundraising | ChainScore Guides