Different execution models, one guarantee. The enforcement lives on the destination chain, not in the relay.
The obvious question, once you say "compliance on every transfer," is whether the same guarantee holds when the transfer happens on a chain that is not Ethereum-compatible. Different virtual machines, different account models, different rules for what a contract is even allowed to do on a token move. It would be easy to answer "yes, mostly" and hope no one looks closely. We have taken the harder route: rebuild the guarantee, from scratch, on each family, using primitives the chain natively supports.
This post walks through what that looks like in three families we care about: Solana, Stellar's Soroban, and Stacks Clarity. If you have ever asked why we bother with three different execution stacks instead of just running the EVM one everywhere, the answer is in the next thousand words.
What EVM gives us that has to be recreated
On EVM chains (Sepolia, Amoy, Plume, Minato), every OB-issued token has a compliance layer attached to it: a Chainlink ACE ComplianceCheck contract that runs every transfer through a modular policy set (identity validator, allowlist, max-balance concentration cap). The token calls the check, the check reads the on-chain policy, and the transfer either goes through or reverts with a precise reason. Simple, auditable, and identical across all four EVM chains because they all share the same runtime.
None of that ports directly. Solana does not have EVM's kind of pre-transfer hook out of the box; you use Token-2022. Soroban has its own contract runtime, but it is not EVM's. Clarity is a decidable, non-Turing-complete language that will refuse to let you write half of what an EVM developer takes for granted. Rebuilding the guarantee means using each family's actual tools, not a lowest-common-denominator wrapper.
Solana: Token-2022 transfer hooks
Solana's SPL Token-2022 program supports transfer hooks: a mechanism where the token can name a program that must run on every transfer, and the transfer only settles if that program returns success. This is the closest analog to EVM's "run a compliance check before the transfer completes." We use it.
The hook program consults an on-chain compliance registry. That registry mirrors the EVM allowlist state through a Chainlink CRE workflow, so an address admitted on Sepolia becomes an admitted holder on Solana within one settlement cycle. The registry entry is a small account keyed by the asset ID and the holder address; the hook reads it, checks the flags (admitted, not sanctioned, within concentration caps), and either signs off or rejects.
The important thing here is where the enforcement runs. It runs on Solana, inside the transfer itself. There is no way for the destination address to receive the asset without the hook returning success. That is the same guarantee we have on EVM, achieved with a completely different mechanism.
Stellar Soroban: lock-and-mint with admission at the mint
Soroban is Stellar's smart contract runtime. It supports pre-transfer control through a different pattern: the token contract itself calls an admission-check contract before every mint or transfer. We use this as the compliance surface for OB-issued tokens on Soroban.
The bridge model is lock-and-mint. When a user moves a token from an EVM source to Stellar, the source-side contract locks the balance and emits an event. A Chainlink CRE (Chainlink Runtime Environment) workflow picks up the event, and a mint call fires on Soroban. The mint call requires the recipient address to be admitted; the admission-check contract reads the local compliance registry and refuses non-admitted mints. Nothing sits in a queue waiting for an off-chain approver to click through. The mint either settles or reverts on-chain, and the revert reason is retained for the relay to surface.
Return flow (Stellar back to EVM) uses the same pattern in reverse: the Soroban side burns, a DON-attested outbound event releases the locked balance on the source chain, and admission is re-checked on both sides.
Stacks Clarity: the Tier-2 asset registry
Stacks is more restrictive. Clarity smart contracts are deliberately non-Turing-complete; there are things you cannot express in the language, and one of them is arbitrary computation on transfer. We work with the restriction rather than against it.
The pattern is a Tier-2 asset registry. Every OB-issued token on Stacks has a companion registry contract that records who is admitted and at what balance cap. Mints and transfers of the token pass through a small guard function that consults the registry; a non-admitted recipient causes the guard to fail. Because Clarity is decidable, we can reason statically about the fact that no token movement can bypass the guard. That is a stronger property than we get on EVM.
The registry is synchronized from the source EVM chain by an attested relay. When a user's admission changes on Sepolia, the registry entry on Stacks is updated within one settlement cycle. The bridge relay is not permitted to change balance caps or admission flags on its own; it can only apply state that a source-chain event has authorized.
The relay is a courier, not an authority. The destination chain will refuse the state change if the policy does not hold, regardless of what the relay claims.
One behavior, three enforcements
The pattern that survives across all three families is: the enforcement runs on the destination chain, at the moment of settlement, using the chain's own primitives. This is what we mean when we say the compliance layer is on every transfer. Not "we have a policy" but "the chain itself will not let the transfer happen if the policy does not hold." An address that has not been admitted for a given asset will see mints and transfers revert, on every chain, using the mechanism that chain natively supports.
This is the same design philosophy that drives Chainlink CCT and Chainlink CCIP: put the enforcement where the state actually lives, not where a coordinator can be talked out of it. On CCT-native EVM chains, that comes essentially for free. On non-EVM chains, it is the build. We did it because "compliance on every transfer" is not honest unless it holds on every chain we support.
What we deliberately did not import
One thing we did not port to non-EVM: the portable credential we use on the EVM side, where one Didit verification satisfies all four EVM chains. Each non-EVM chain uses its own native identity module instead. That is a deliberate choice, not a shortcut. A cross-chain identity object with a single source of truth is only as strong as the weakest chain's ability to enforce it locally, and the honest thing to do is give each non-EVM chain a native module it can enforce on its own, rather than pretend the EVM credential is universal. When and if Chainlink's cross-chain infrastructure arrives natively on those chains, the model will collapse to one.
The trade is worth naming. On EVM, verify once and you are admitted on four chains; on non-EVM, each chain owns its identity gate. The floor is the same on all of them: no chain will move a regulated asset to an address that is not admitted, and no relay can override that.
Try the demo
The full loop is live on testnet: onboard a wallet, move a token from an EVM chain to a non-EVM chain, and watch the destination contract enforce admission at settlement. The agent-focused version of this same design is worth reading next, since it shows why identical enforcement matters when an autonomous program is the one initiating the transfer.
Testnet, unaudited. Not a solicitation. Not an offer of securities. Every transaction you make on this site is signed by your own wallet on a public testnet. No real money moves.
Testnet, unaudited. Not a solicitation. Not an offer of securities. Every transaction you make on this site is signed by your own wallet on a public testnet. No real money moves.