Skip to main content
Any data, whether it’s a fungible token transfer, an NFT, or some other smart contract input can be encoded on-chain as bytes and delivered to a destination chain to trigger some action using LayerZero. Because of this, any blockchain that broadly supports state propagation and events can be connected to LayerZero, including Starknet.
If you’re new to LayerZero, we recommend reviewing “What is LayerZero?” before continuing.

LayerZero provides Starknet Cairo Contracts that can communicate with the equivalent Solidity Contract Libraries and Solana Programs deployed on other chains. These contracts, like their Solidity and Rust counterparts, simplify calling the LayerZero Endpoint, provide message handling, interfaces for protocol configurations, and other utilities for interoperability:
  • Omnichain Fungible Token (OFT): extends OApp with functionality for handling omnichain token transfers using Starknet’s ERC20 standard.
  • Omnichain Application (OApp): the base contract utilities for omnichain messaging and configuration.
Each of these contract standards implements common functions for sending and receiving omnichain messages.

Differences from the Ethereum Virtual Machine

The full differences between Solidity/EVM and Cairo/Starknet are significant. For comprehensive guides, see:
Skip this section if you already feel comfortable working with Starknet and its account abstraction model.

Comparison Table

Account Abstraction (No EOAs)

The most fundamental difference is Starknet’s native account abstraction: EVM:
Starknet:
Key Implications:
  • Before deploying any contract, you must have a deployed and funded account contract (wallet)
  • Signatures are produced off-chain by the account owner and validated by the account contract
  • Account contracts handle fee payment and transaction execution for that account
  • Common account implementations include Ready Wallet (formerly Argent), Braavos, and OpenZeppelin Account

Declare Then Deploy Lifecycle

Unlike EVM where you deploy bytecode in a single transaction, Starknet separates code publication from instantiation: Step 1: Declare - Publish your contract code to the network:
Step 2: Deploy - Create an instance of the declared class:
Key Concepts:
  • class_hash: Unique identifier for your contract’s code (like a “template”)
  • contract_address: Specific instance of that code with its own state
  • Multiple contracts can share the same class_hash (reusable code)

Dispatcher Pattern vs Inheritance

Starknet uses the dispatcher pattern instead of Solidity’s inheritance model. EVM uses inheritance for contract composition:
Starknet uses components and dispatchers:
Cross-contract calls use dispatchers:

Constructor Caller Footgun

When deploying via the Universal Deployer Contract (UDC), get_caller_address() in the constructor returns the UDC address, not your account address!
Problem:
Solution - Always pass the owner explicitly:

Cairo Integer Types

Cairo 1.0 provides native unsigned integer types. For token amounts (ERC20 balances, transfers, allowances), always use u256—matching Solidity’s uint256 for crosschain compatibility. OpenZeppelin’s Cairo ERC20 interface uses u256 for balance_of, total_supply, allowance, and all transfer/approve amounts.
You’ll also encounter felt252 in Cairo—it’s Starknet’s base field element type used internally (e.g., ContractAddress wraps a felt252). However, don’t use it for token amounts; its modular arithmetic can cause unexpected behavior.
Crosschain encoding: LayerZero messages encode addresses as Bytes32 for compatibility across chains with different address sizes.

Resource Bounds (Gas Model)

Starknet uses resource bounds instead of simple gas limits:
Common error: “Insufficient max fee” - increase your resource bounds (or fee cap in tooling):

Prerequisites

Before you start building, you’ll need to set up your development environment.

1. Deploy and Fund an Account Contract

Unlike EVM, you need an account contract before you can deploy other contracts:
Create a new account (generates keys and computes address)
Fund the computed address with STRK/ETH before deploying.
The account create command outputs the computed address. Fund this address using a faucet before running account deploy.
Deploy the account contract

2. Account File Location

Accounts are stored in ~/.starknet_accounts/starknet_open_zeppelin_accounts.json:

3. Install Scarb (Cairo Build Tool)

Scarb is the official Cairo package manager and build tool:
Verify installation:

4. Install Starknet Foundry (sncast + snforge)

Starknet Foundry provides sncast (deployment) and snforge (testing):
Verify installation:
RPC Version Compatibilitysncast requires a compatible RPC version:
  • Starknet Foundry 0.53.0+ expects RPC v0.9.0 or v0.10.0
  • Starknet Foundry 0.49.0 expects RPC v0.9.0
If you see RPC node uses incompatible version warnings, update your RPC URL to use a compatible version:

5. Configure snfoundry.toml

Create a snfoundry.toml in your project root to configure sncast defaults:
Use sncast account list to see available account names.

6. Install Node.js

For any TypeScript tooling or SDK usage:

7. Get Testnet STRK/ETH

For testing on Starknet Sepolia testnet:

Project Structure

A typical LayerZero Starknet project structure:
Example Scarb.toml:
Installing LayerZero PackagesBefore building, install the LayerZero Cairo contracts:

Network Configuration

SN_MAIN and SN_SEPOLIA are Starknet’s native chain-id identifiers, defined by the Starknet protocol to identify the target network for transactions.
RPC Endpoints:
  • Mainnet: <YOUR_MAINNET_RPC_URL>
  • Sepolia: <YOUR_SEPOLIA_RPC_URL>
RPC providersBlast public endpoints are deprecated; use Alchemy, Infura, or another provider that supports Starknet JSON-RPC v0.9+.

Next Steps

Choose your path:

Build an OApp

For custom crosschain logic:

Build an OFT

For crosschain tokens:

Understand the Protocol

For protocol-level understanding:

Get Help