LayerZero on Canton is not yet open for self-service integrations. The Canton contract packages and deployment tooling are not public. Steps that depend on LayerZero start with “Work with LayerZero Labs” and say what happens in that step. To start an integration, contact the LayerZero team.
How an OFT Works on Canton
On Canton, LayerZero connects an existing CIP-0056 token, for example a token issued through Digital Asset’s registry, with an OFT adapter. The adapter is a set of Daml contracts. The OApp admin signs them. It is usually the asset issuer. For Canton Coin, it is theccadapter party that LayerZero Labs administers (see Parties Involved). The adapter reaches the LayerZero Virtual Endpoint Rollup (VER) through request contracts on the ledger.
Adapter Models
The LayerZero Canton packages support two adapters:
With both adapters, the receiver gets a CIP-0056 transfer instruction. If the token’s transfer rules require it, the receiver accepts the instruction in a separate transaction, usually through its wallet. The instruction expires after 24 hours, and the tokens return to the custody or mint escrow party. LayerZero does not resend an expired instruction automatically. To have the tokens delivered again, contact the LayerZero team. For Canton Coin, a receiver with a transfer preapproval gets the tokens without a separate accept.
The burn/mint adapter has a second signatory, a mint escrow party. The lock/unlock adapter has a second signatory, the custody party that holds locked assets. Both must be different from the OApp admin.
A burn/mint adapter can burn and mint only through a burn/mint factory that the OApp admin controls. If the token’s instrument admin is a different party, the instrument admin creates a
BurnMintDelegate contract for the token. This contract gives the OApp admin burn and mint rights for that one instrument. The instrument admin can revoke these rights by archiving the contract.
Parties Involved
Decimals
The adapter’s configuration contract (AdapterConfig for lock/unlock, BurnMintAdapterConfig for burn/mint) stores localDecimals (at most 10 on Canton) and sharedDecimals. As on other chains, the amount in a LayerZero message uses shared decimals. Pick a sharedDecimals value that every chain in your mesh supports. The OFT standard explains shared decimals.
Prerequisites
- A participant node for your parties. Run your own validator node, or use a party hosted on another operator’s node. A validator node needs a Super Validator sponsor to join the Global Synchronizer.
- Ledger API access to that participant node, with rights to submit commands as your parties.
- Parties. Allocate the OApp admin party and a fee deposit party on your participant node. Allocate the custody or mint escrow party too, unless you agree in Step 1 that another operator runs it. See Manage Daml Parties.
- An existing CIP-0056 token. Choose the lock/unlock or the burn/mint adapter. For the burn/mint adapter, the token must have a CIP-0056 burn/mint factory.
- Amulet (Canton Coin) on your parties, to pay for traffic, endpoint request fees, and registry fees.
- A Canton 3.x environment. The LayerZero packages target Canton 3.x and the Daml 3.x SDK.
- An EVM deployer for the remote side, set up as in the EVM OFT quickstart.
Step 1: Agree on the Integration
Work with LayerZero Labs to start the integration. In this step, you and LayerZero agree on:- The adapter model and the networks: LayerZero testnet (Canton DevNet) first, then mainnet
- The EVM chains to connect
- Who operates which parties, including the mint escrow or custody party for an adapter
- The send and receive security settings (DVNs and confirmations)
Step 2: Get the LayerZero Package Set and Protocol References
Work with LayerZero Labs to receive these items:- The LayerZero DAR packages. See LayerZero Packages.
- The protocol references that your contracts point to. These are the
lzownerparty, which observes your OApp and handles its requests, the request factory contract, and the endpoint address that the adapter configuration stores. - The disclosures for the LayerZero-signed contracts that your transactions use, such as the request factory. Your participant node cannot see these contracts, so each submission must attach them as disclosed contracts.
Step 3: Upload and Vet the Packages
Upload the DAR packages to your participant node. Canton vets a package as part of the upload by default. See Manage Daml Packages. Every participant node that takes part in a transaction with your token must vet the same packages. This includes the participant nodes of your users’ wallets. Plan this with your wallet providers before launch.Step 4: Create the Adapter Contracts on Canton
Submit these commands as the OApp admin. None of these contracts needs a signature from LayerZero. Each contract listslzowner (from Step 2) as an observer when you create it. This lets LayerZero see your contracts, so it can process your requests and provide the disclosures that senders and the executor need.
- Burn/mint delegate (burn/mint adapter only). If the token’s instrument admin is not the OApp admin, the instrument admin creates a
BurnMintDelegatefor the token. It names the OApp admin as the delegate, the token’s burn/mint factory, andlzownerasoappGateway. - Adapter. Create
LockUnlockAdapterorBurnMintAdapterwith the OApp ID andlzownerasoappGateway. The OApp ID is the OApp admin party and an ID string that you choose. The custody party (lock/unlock) or the mint escrow party (burn/mint) is the second signatory, so it must also authorize this command. - Configuration. Create
AdapterConfig(lock/unlock) orBurnMintAdapterConfig(burn/mint). It holds:- the OApp ID and the token’s instrument ID
localDecimalsandsharedDecimals- the fee deposit party and the fee in basis points per destination EID
- the request factory and the endpoint address from Step 2
- the rate limiter configuration (rate limiting can be disabled)
- empty maps for peers and enforced options, which you set in Step 6
- the observers of the configuration, including
lzowner
- Receiver registry. Create a
Registryand itsRegistryConfig. On receive, the adapter uses the registry to turn the 32-byte receiver in the message into a Canton party. The configuration sets an optional registration fee and a maximum number of entries. - Access control and rate limiter state. Create an
AccessControlcontract if you want to give roles to other parties, for example a manager or a fee manager. Without it, only the OApp admin can run administrative choices. Create aRateLimiterStatecontract if you use rate limits.
Contract IDs change when you update a contract. Each configuration choice in Step 6 archives the adapter configuration and creates a new one. Read the current contract ID from the ledger after each change.
Step 5: Set the Endpoint Configuration
On Canton, endpoint settings are requests, not direct calls. For each setting, the OApp admin exercisesOApp_CreateRequest on the adapter. The request carries the endpoint call and pays the request fee in Amulet. VER processes the request, and the lzowner party accepts it.
Submit one request for each of these endpoint calls:
Work with LayerZero Labs to get the current request fee and to agree on the values. Hold enough Amulet on the OApp admin for every request. Do not submit a second request for the same setting while the first one is still pending.
DVNs on Canton. Canton DVNs are deployed once per DVN provider, at the protocol level, as on other chains. You do not deploy DVN contracts for your OApp. You choose DVNs in
setSendConfig and setReceiveConfig. For the DVNs that verify Canton Coin messages on Canton mainnet, see DVN Providers. Use the DVN addresses that LayerZero Labs confirms in Step 1.
Step 6: Configure the Adapter on Canton
Exercise these choices on the adapter configuration as the OApp admin, or as a party with the required role. They do not go through VER and do not need a LayerZero signature.
Set rate limits with the rate limiter choices on the adapter configuration (rate limiter manager role). The
RateLimiterState contract tracks usage.
Step 7: Deploy and Wire the EVM Side
Deploy an OFT on the EVM chain with the standard tooling, as in the EVM OFT quickstart. Then wire it to Canton:-
Set the peer. Call
setPeeron the EVM OFT with the Canton EID (30567for mainnet,40567for LayerZero testnet on Canton DevNet) and the adapter’s 32-byte OApp address. The address is derived from the adapter’s OApp ID: the OApp admin party ID and the ID string from Step 4:Use the ID string of the OApp ID, which can differ from the token’s instrument ID. Work with LayerZero Labs to confirm the address before you set it. - Set the DVNs. Configure the same DVN set on the EVM send and receive configuration as on the Canton side. See DVN and Executor Configuration.
- Set the confirmations for each direction to the values agreed in Step 1.
- Set enforced options for sends to Canton.
-
Match decimals. Use the same
sharedDecimalson the EVM OFT as in the adapter configuration.
Step 8: Register Receivers
A LayerZero message names its receiver with 32 bytes. A Canton party ID ishint::1220<64 hex characters>. Canton calls everything after :: the fingerprint: 1220 is a multihash header for SHA-256, followed by a 32-byte digest. LayerZero calls the 64 hex characters of that digest the fingerprint, and this page uses that meaning. The message carries only those 32 bytes, and the adapter’s registry maps them back to the full party. Canton treats party IDs as opaque, so this mapping is a LayerZero convention. For Canton Coin, use the Value Transfer API or Stargate to derive it.
Before a party can receive tokens from another chain, it must register in the adapter’s registry. The party exercises SetPartyId on the Registry with its hint, and pays the registration fee from its own holdings if the configuration sets one. The registry key is the fingerprint of the party that exercises SetPartyId, and the hint is a value that party supplies. A party with its own namespace, such as an external party created with its own key, is the only party that can register its fingerprint. Parties that share a namespace can each set or replace the entry for that shared fingerprint. For Canton Coin, use the Value Transfer API or Stargate to register: they derive the hint from the full party ID and refuse to re-point a namespace that another party holds. A wallet can ask its user to sign the registration during onboarding.
If a party is not registered, delivery to it waits. The tokens stay burned or locked on the source chain. The lzReceive request is accepted, but its settlement cannot complete. The LayerZero executor can retry the settlement after the party registers, and the delivery can then complete.
Send from Canton to the EVM Chain
- Get the fee. The fee is quoted from VER off the ledger, through the read API of LayerZero’s VER sequencer (see VER). Get an access token from LayerZero Labs.
- Submit. The sender’s wallet exercises
OApp_LzSendon the adapter. The command includes:- the send parameters: destination EID, receiver (the 32-byte EVM address), amount, minimum amount, extra options, and an optional compose message
- the sender’s token holdings to spend
- Amulet holdings and the fee amount for the protocol fee
- the configuration, rate limiter, and request factory references
- the disclosed LayerZero contracts from Step 2
- Settle. The lock/unlock adapter moves the amount to the custody party, and the burn/mint adapter burns it. The send also creates a request. VER processes it, and the
lzownerparty accepts or rejects it. On accept, VER emits the packet and the DVNs verify it. The LayerZero executor settles an accepted send separately. For rejected sends and refunds, see Step 5. - Receive on EVM. The DVNs verify the packet, and the executor calls
lzReceiveon the EVM OFT, which credits the receiver as on any EVM pathway.
Send from Another Chain to Canton
A send into Canton is different from a send between EVM chains. The source chain cannot check the receiver, so the receiving party must be ready on Canton before anyone sends.- The message carries only part of the receiver’s address. The
tofield holds the 32-byte fingerprint of the party ID. The adapter’s registry on Canton maps it back to the full party ID (see Step 8). - The receiver must register first, on Canton. A party registers by signing
SetPartyIdwith its own Canton wallet or key and paying the fee from its own holdings on Canton. No source-chain transaction can register it. Parties that share a namespace can each set the entry for that namespace (see Step 8). - The receiver’s participant node must run the LayerZero packages. To register, the node that hosts the party must have uploaded and vetted the LayerZero packages. Many Canton wallets and custodians do not run them.
Recommended: Build the Send with LayerZero Tooling
For Canton Coin, use Stargate or the Value Transfer API. They take the full Canton party ID and convert it to the 32-byte receiver value. They refuse to build a transfer if the party is not registered or if its fingerprint is registered to a different party. The Value Transfer API also prepares the registration transaction for the receiving party, which signs it on Canton with its own wallet. Neither can register the party from the source chain. For other tokens on Canton, work with the token issuer or LayerZero Labs before you build sends, and check every item in the pre-send checklist.Build the Send Yourself
- Encode the receiver. Set
toin theSendParamto the receiver party’s fingerprint: the 64 hex characters after1220in its party ID, as 32 bytes. Do not hash the party ID. Do not use an EVM address, a Solana address, or the hint. - Send. Call
quoteSendandsendon the OFT, as on any pathway. See the EVM OFT quickstart. LeavecomposeMsgempty. A Canton OApp rejects any inbound message that carries a compose message, so the delivery never completes and the tokens stay burned or locked on the source chain. Registering the receiver does not fix this. Do not set a native drop. The fee is charged, but nothing is delivered on Canton. - Automatic delivery. After the DVNs verify the packet, the LayerZero executor delivers it into Canton. VER processes the request, and the executor settles it. The adapter’s callback resolves the receiver through the registry. The receiver then gets a CIP-0056 transfer instruction from the custody party or the mint escrow party. The receiver may need to accept it in a separate transaction, depending on the token’s transfer rules. The instruction expires after 24 hours. LayerZero does not resend an expired instruction automatically. To have the tokens delivered again, contact the LayerZero team.
- Rate limits. If an inbound rate limit is reached, the
lzReceiverequest is still accepted, and the settlement waits. The LayerZero executor retries the settlement after the limit’s capacity recovers.
If the Receiver Is Not Ready
In every case below, the tokens are already burned or locked on the source chain. The sender cannot cancel or reverse the transfer from the source chain.
The adapter stores the amount in local decimals as a 64-bit integer, so the per-message cap is (2^63 − 1) / 10^
localDecimals tokens. This is not a Canton or holding limit. For Canton Coin, the cap is about 922 million CC per message.
Pre-Send Checklist
Check every item before the first send to a Canton party, and again if the party or its node changes.- The receiving party exists and is funded. It holds Canton Coin on Canton for the registration fee, and its own Canton wallet or key can sign the registration.
- Its node runs the LayerZero packages. Every node that hosts the party has vetted the LayerZero packages. The node operator vets each new LayerZero package version.
- The party is registered for this token. For Canton Coin,
POST /v1/register-canton-partyon the Value Transfer API withoutholdingsreturns{"status": "registered", "partyId": "<partyId>"}. - The fingerprint is not taken by another party. If the fingerprint is registered to a different party, the same call returns HTTP 409 (
…its namespace is already registered to a different party). Do not send: the tokens would go to that party. - The receiver value is the fingerprint.
tois the 64 hex characters after1220in that party ID, as 32 bytes. - The party can accept the transfer. For Canton Coin, the party has a transfer preapproval (One-step Transfers in Loop), or someone accepts the transfer instruction within 24 hours.
- No compose message and no native drop are set on the send. A compose message makes the delivery fail (see If the Receiver Is Not Ready).
- Send a small test amount first, and confirm that it arrives on Canton before you send more.
Verify the Transfer
- On Canton, look up the transaction or the receiver’s holdings in Lighthouse, or read the holdings from the receiver’s participant node.
- On the EVM chain, check the transaction in the chain’s block explorer.
- Trace a message end to end by its GUID or source transaction hash with the LayerZero Scan API. For a send from Canton, Scan indexes the transaction in which
lzownercommits the VER result, not the update ID that your wallet returns.
Next Steps
- Protocol Overview: how VER processes requests
- Technical Overview: the Canton model behind each step
- EVM OFT quickstart: the EVM side in detail