An example LayerZero dApp built on top of Next.JS
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.
If want to contribute to the development of the shared packages, you can also clone this repository and run the example app (see the repository home page for more details):
# Clone the repository - this also includes reusable packages
git clone https://github.com/LayerZero-Labs/factory.git && cd factory
# Install required dependencies
yarn
# set up .env
cp .env.example .env
# After a fresh clone, you'll need to run an initial build
yarn build
# To only run the example app (on port 3009)
yarn dev --filter=bridge-app
# To also make changes to the reusable packages
yarn dev
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
The config file defines and exports an object of type AppConfig
. This will describe every token you want to support. The bootstrap file takes that config as an input and hydrates the stores with data and apis to handle bridging all the defined assets. If you are coming from create-lz-app
, your config file will contain exactly what you configured in the cli steps, or the default configuration if you chose that option.
Your bridge will be fully functional out of the box for any bridge type. We have the following Next.js pages:
- bridge: Transfer between any valid pair of registered tokens.
- OFT: A simplified transfer form designed to swap just one type of OFT between supported networks.
- ONFT: Transfer ONFTs across supported networks.
You can include or delete any of these pages to customize the exact application you want to build. For information on how to simplify your repo see the relevant section below.
Your configuration should include some fungible tokens, either OFTs, wrapped assets, or tokens supported by our Aptos or Stargate contracts. In this case, your bootstrapping step will set up the bridgeStore
with everything it needs, including access to the supported currencies and apis to execute transfers.
If you are not interested in including an ONFT bridge, you can completely remove the onft folder, as well as the /onft page. Next you will have to remove imports from the onft
folder and refrences to the onftStore
in bootstrap.ts, everything should be under the heading // ONFT ERC721 & ERC1155
. Once that's done, feel free to remove dependencies related to the ONFT bridge, namely @layerzerolabs/ui-bridge-onft
. You will also want to delete the ONFT tab from the AppHeader
component in your layout.
By default we also include an OFT page. This uses the same bridgeStore
as the full transfer form, so no code needs to be removed. You may remove the /oft page and OFT tab from the layout.
The OFT page is a simplified version of the full transfer form. This page uses the first oft
from your AppConfig
and is a good choice if you are only interested in transferring one token between its supported networks.
If you are only interested in this page you may remove the onft folder, as well as the /onft page. The same bridgeStore
that supports the full transfer page is used in the OFT page so it should not be modified. Similar to above, you will have to remove imports from the onft
folder and references to the onftStore
in bootstrap.ts, and can remove the @layerzerolabs/ui-bridge-onft
dependency.
If your AppConfig
includes any items in the onft
field, the bootstrapping step will automatically configure your onftStore
to support transfers of all your collections across their respective supported networks. The scaffold will also include a store and UI for bridging fungible tokens, if you don't need this you can completely remove the bridge folder, as well as the Bridge
and OFT
tabs from the AppHeader
component in your layout. You will then have to remove imports from the bridge
folder and references to the bridgeStore
from bootstrap.ts, and can remove all dependencies related to fungible token bridging.
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.
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.
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.
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.
Main Net: https://bridge.telos.net
Test Net: https://telos-bridge-testnet.netlify.app