Permissionless base permissioned app layer
Who this is for: protocol-minded engineers and issuers deciding where to put a permission check in their own contract. For the four named checks that get built on top of this pattern, see Compliance model overview.
The core split
Lumia's chain layer (sequencing, the zkEVM, state transitions, the data-availability layer) does not gate who can transact. Any address can send a transaction, deploy a contract, or hold a token, the same as on Ethereum or any general-purpose EVM chain. There is no protocol-level allowlist of wallets.
Compliance instead lives at the application layer, enforced by the contracts an issuer deploys. This is a deliberate architectural choice: it means Lumia can host fully permissionless, DeFi-style contracts and tightly gated RWA contracts side by side on the same base layer, each choosing its own rules, rather than the whole chain adopting one compliance regime for every application.
Why the base layer doesn't enforce this itself
A chain that enforced identity checks at the protocol level would need to verify identity before including a transaction in a block: effectively an allowlisted sequencer. That trades away permissionless access and composability for every application on the chain, including ones that don't need compliance at all. Lumia's application-layer approach avoids that trade-off by leaving the choice to each contract instead.
How an app opts in
The general pattern is a permission check inside the contract itself (typically a transfer() override or a modifier gating a sensitive function) that calls out to an identity or eligibility registry before allowing the action:
// Illustrative pattern, not a copy-paste production contract.
// See ../../build/identity/on-chain-kyc-integration.md for the actual verifier integration steps.
modifier onlyVerified(address account) {
require(kycRegistry.isVerified(account), "not verified");
_;
}
function transfer(address to, uint256 amount)
public
onlyVerified(msg.sender)
onlyVerified(to)
returns (bool)
{
// standard ERC-20 transfer logic
}This is the same general pattern most permissioned-security-token standards use (compare to ERC-1400's transfer restrictions or ERC-3643's identity registry): the token contract checks an identity/eligibility registry at the moment of transfer, rather than the chain checking identity before the transaction is even included.
What's enforced where
Protocol (base chain)
Nothing identity-related; open access
Anyone can submit a valid transaction
Application (contract)
Whatever the issuer builds
transfer() requires a verified-credential check
Off-chain (issuer's own process)
The actual KYC/KYB/KYT decision-making
A compliance team or vendor approves an applicant, reflected on-chain
Last updated
Was this helpful?