LayerZero

LayerZero Bridge Example dApp

Deploy with Vercel Deploy to Netlify

An example LayerZero dApp built on top of next.js

Quick Start

The easiest way to create a dApp for your LayerZero tokens is to use our create-lz-app utility:

npx create-lz-app ./my-project-directory

This utility will walk you through the process of dApp configuration and will create a working Next.js application you can then deploy using e.g. Vercel or Netlify.

Development

This app adheres to Next.js standards so the development workflow should feel pretty familiar:

# Let's asssume you are using yarn as a package manager

# To install dependencies
yarn

# To start a development server
yarn dev

# To create a production build
yarn build

Project Structure

The example app is organized by feature. You’ll find verticals for the fungible token bridge and non-fungible token (ONFT) bridge in the features folder, along with core pieces used in each. Within each vertical folder you’ll find stores, components, and configuration specific to that use case.

bridge-app
├── README.md
├── node_modules
├── package.json
├── tsconfig.json
├── public
│   └── static
│        └── icons
└── src
    ├── config.ts
    ├── bootstrap.tsx
    ├── features
    |  ├──core
    |  ├──bridge
    |  └──onft
    └── pages
      ├── bridge.tsx
      ├── oft.tsx
      ├── onft.tsx
      └── _app.tsx

Configuration

The app is initialized in the _app.tsx file where we call the bootstrap function that sets up our generic stores, wallet configuration, and registers the tokens we want to support.

Tokens

All of your token configuration should live in the root config file. Here you will define your lzAppConfig which will describe exactly which tokens of which type your bridge will support. The example app ships with support for OFT and Wrapped Assets in the Fungible Token Bridge and ERC721 and ERC1155 in the Non-fungible Token Bridge.

To specify which tokens you want to support, modify the lzAppConfig with your own configuration. See the Fungible Token Bridge App and Non-fungible Token (ONFT) Bridge App readmes for more details on what is supported out of the box, and how to set up your own configuration.

export const lzAppConfig = {
  bridge: {
    oft: [
      //
      oft_mainnet.BTC,
      oft_mainnet.JOE,
      oft_mainnet.PEPE,
      oft_testnet.CAKE,
      oft_testnet.BTC,
    ],
    wrappedAsset: [
      //
      wrapped_mainnet,
      wrapped_testnet,
    ],
    onft: [
      //
      erc721_testnet,
      erc721_mainnet,
      erc1155_testnet,
    ],
  },
};

Wallet Configuration

The example app ships with support for the following wallets

  • Petra
  • Fewcha
  • Martian
  • Wallet Connect
  • Metamask
  • Phantom
  • Coinbase Wallet
  • Core
  • Pontem
  • Brave
  • PhantomEvm
  • Solflare
  • Coinbase Wallet Solana

You can enable any combination of these in the createWallet helper by adding or removing from the wallets array.

Providers

Some stores require blockchain or api communication. To do this we abstract this layer into providers, and assign them to the store on initialization.

An example is the fungible token balanceStore that needs to know how to get balances from any wallet type. In the bootstrap file, we add three providers that act as the infrastructure layer for the balanceStore.

balanceStore.addProviders([
  new BalanceProvider__aptos(aptosResourceProvider),
  new BalanceProvider__evm(providerFactory),
  new BalanceProvider__solana(new SolanaConnection('https://api.devnet.solana.com')),
]);

Each provider is aware of which type of balance it supports and selects itself to provide the balance in those cases.

ONFT Balances Providers

To read ONFT balances for your collection you will likely need to implement your own balance provider. We recommend using a third party indexing service like Alchemy, Infura, or Simple Hash.

Your custom provider should implement the ONFTBalanceProvider interface

interface OnftBalanceProvider {
  supports(contract: OnftContract): boolean;
  getAssets(contract: OnftContract, owner: string): Promise<OnftTokenAmount[]>;
}

Where supports returns true if the contract address belongs to your collection, and getAssets should request assets from your third party integration. Once implemented, you can swap the default balance provider in bootstrap.ts to complete your configuration.

RPC Provider

The core bootstrap is where we initialize a providerFactory. In this context we're referring to rpc node providers, and the factory maps a chainId to a FailoverProvider. See the ui-evm documentation for more details, in short we connect to RPC nodes based on a weighted score, and fallback to another option in case of multiple failures.

The providerFactory is used in some the the generic store providers and is sent to the app specific bootstrapping steps.

Included Apps

Create a fungible token bridge that can transfer OFTs, wrapped assets, native assets, and ERC20s across networks.

Create an app that can bridge Omnichain Non-fungible Tokens.

Disclaimer

DISCLAIMER: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.