Professional Documents
Culture Documents
Wormhole Development Book
Wormhole Development Book
html
Introduction
An Introduction to
xDapps
This chapter aims to give you a clear
understanding of what xDapps are and why
they're gaining traction in the blockchain
development community.
Ecosystem Basics
Since the launch of Bitcoin in 2009, the
cryptocurrency and decentralized computing
ecosystem has rapidly evolved and expanded.
The ecosystem now includes hundreds of
blockchains, often also referred to as Layer 1s.
Blockchain
Interoperability
Because blockchains are siloed by nature,
individual cryptocurrencies being bound to their
own chains has been a longtime limitation of
blockchain technology. The first attempt at
solving this problem was the creation of
cryptocurrency exchanges like Coinbase and
Binance. Today these are refered to as
centralized exchanges (CEXs).
What is an xDapp?
The term xDapp is short for "Cross-Chain
Decentralized Application". At first glance, this
might give the impression that xDapps are simply
Dapps that do cross-chain things. However, once
you start building decentralized products
designed to operate across a variety of
blockchains and runtimes, it becomes clear that
these applications are architected in a
fundamentally different way than traditional
Dapps.
Advantages of xDapps
Here are a few xDapp features that are making
an impact across blockchain technologies:
Wormhole
In the previous chapter, we established concepts
like xDapps, xData and xAssets. In this chapter,
we'll focus on the inner workings of the
Wormhole ecosystem and how they power these
ideas.
What is Wormhole?
Wormhole V1 was introduced in 2020 by Certus
One, and was initially conceived as a traditional
token bridge between Ethereum and Solana. It
served as the first bridge on Solana and was
responsible for bootstrapping a large amount of
the liquidity in the early Solana and Serum
ecosystems.
Architecture Overview
Wormhole is a complex ecosystem with several
noteworthy components. Before we go into each
component in depth, let's talk about the names
of the major pieces and how they fit together.
On-Chain Components
Off-Chain Components
Core Contracts
The Core Contracts are the mechanism by which
all Wormhole messages are emitted. All xDapps
either interact directly with the Core Contract or
interact with another contract that does. There is
one Core Contract on each blockchain in the
ecosystem, and this is the contract which the
Guardians are required to observe.
Sending
publishMessage(
int nonce,
byte[] payload,
int consistencyLevel
) returns int sequenceNumber
Receiving
Multicasting
Let's take a moment to point out that there is no
destination address or chain in these functions.
Header
Body
u32 timestamp
(Timestamp of the block where the source
transaction occurred)
u32 nonce (A
grouping number)
u16 emitter_chain
(Wormhole ChainId of emitter contract)
[32]byte emitter_address
(Emitter contract address, in Wormhole
format)
u64 sequence
(Strictly increasing sequence, tied to
emitter address & chain)
u8 consistency_level
(What finality level was reached before
emitting this message)
[]byte payload (VAA
message content)
Batch VAAs
Certain blockchains support version 2 VAAs, also
referred to as Batch VAAs which are designed to
provide an easier paradigm for composability
and better gas efficiency when multiple cross-
chain actions are involved in a single transaction.
Guardian Network
The Guardian Network is designed to serve as
Wormhole's oracle component, and the entire
Wormhole ecosystem is founded on its technical
underpinnings. It is the most critical element of
the Wormhole ecosystem, and represents the
single most important component to learn about
if you want a deep understanding of Wormhole.
Decentralization
Decentralization is the biggest concern. Previous
interoperability solutions have largely been
entirely centralized, and even newer solutions
utilizing things like adversarial relayers still tend
to have single points of failure or collusion
thresholds as low as 1 or 2.
Modularity
The Guardian Network is robust and trustworthy
by itself, so there's no need for components like
the relayer to contribute to the security model.
That makes Wormhole able to have simple
components that are very good at the one thing
they do. That way, Guardians only need to verify
on-chain activity and produce VAAs while
Relayers only need to interact with blockchains
and deliver messages.
Chain Agnosticism
Today, Wormhole supports a wider range of
ecosystems than any other interoperability
protocol because it uses simple tech (t-schnorr
signatures), an adaptable, heterogenous relayer
model, and a robust validator network.
Scalability
Wormhole scales well, as demonstrated by its
ability to handle huge TVL and transaction
Upgradability
Over time, the Guardian Set can be expanded
beyond 19 with the use of threshold signatures.
A variety of relaying models will emerge, each
with their own strengths and weaknesses. ZKPs
can be used on chains where they are well
supported. The xDapp ecosystem will grow, and
xDapps will become increasingly intermingled
with eachother. There are very few APIs in
Wormhole, and most items are implementation
details from the perspective of an integrator. This
creates a clear pathway towards a fully
trustlessness interoperability layer which spans
the entirety of decentralized computing.
Relayers
All simple cross-chain processes on Wormhole
essentially boil down to a three-step process:
Client-side Relaying
Client-side relaying relies on the user-facing
frontend, like a webpage or a wallet, to perform
all three steps of the cross-chain process.
Specialized Relayers
Specialized relayers solve the UX problems of
client-side relayers by adding a backend
Generic Relayers
Note: this feature is not yet available in mainnet
xAsset Layer
There is a set of ecosystem contracts that
provision Wormhole's xAsset layer which allow
tokens to be bridged around the Wormhole
Ecosystem in a path-independent fashion, and
are easily composable with other functions in the
Wormhole ecosystem.
Creating xAssets
xAssets always have an origin chain. This is
where the token is initially minted via the
standard of that chain (ERC-20, SPL, etc for
tokens; ERC-721, Metaplex, etc for NFTs).
Tokens
function attestToken(
address tokenAddress,
uint32 nonce)
returns (uint64 sequence)
function createWrapped(
bytes memory encodedVm)
returns (address token)
NFTs
Transferring xAssets
Initiating xAsset transfers is a straightforward
affair. Once the transfer is initiated, the
Guardians will produce a transfer VAA when
finality has been reached on the source chain.
The VAA must then be relayed to the target
chain.
Tokens
function transferTokens(
address token,
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
uint256 arbiterFee,
uint32 nonce) returns (uint64
sequence)
NFTs
function transferNFT(
address token,
uint256 tokenID,
uint16 recipientChain,
bytes32 recipient,
uint32 nonce) returns (uint64
sequence)
)
Contract-Controlled Transfers
Basic transfers are intended to transfer xAssets
from one wallet to another, whereas Contract
Controlled Transfers (CCTs) are meant to transfer
xAssets from one smart contract to another. If
you're writing an xDapp, CCTs will likely be a
large component.
Wormchain
Wormchain is a purpose-built cosmos blockchain
for the Wormhole ecosystem. It has two primary
functions:
xDapp Design
Now that we've established the major concepts
and components underlying xDapps, let's dive
into the process of designing one. This chapter
will guide you through the considerations you
should make before developing an xDapp,
including topics like network topology, protocol
design and more.
Key Considerations
Before we get started, we should outline the key
considerations that will shape your xDapp.
Below, we'll show how each of the decisions you
make about these key considerations can impact
the structure of your application as a whole.
Why?
Data Flows
Ecosystems
At present, there are 6 ecosystems supported by
Wormhole, though the number of supported
ecosystems is always growing.
EVM
Example chains:
- Ethereum
- Polygon
- BNB Chain
- Avalanche (C Chain)
- Aurora (Near Network)
- Karura (Polkadot Network)
- Acala (Polkadot Network)
- Celo
- Fantom
- Oasis (Emerald)
Solana
Cosmos
Algorand
Aptos
NEAR
Read-Only Chains
Protocol Design
They key feature of Wormhole is bringing
message passing to the world of blockchain, so
it's worthwhile to take some inspiration from
other areas of software development that are
based on similar principles.
Address Space
Topology
Topology describes how data flows through your
application and defines the responsibilities of
each component. In terms of overall xDapp
topology, the primary decision is determining
where your smart contracts will live and the
responsibilities each contract will hold.
Ultra-light Clients
Advantages:
Disadvantages:
Hub-and-Spoke
Advantages:
Disadvantages:
Mesh
Advantages:
Disadvantages:
Distributed
Advantages:
Disadvantages:
Relayers
In Chapter 2, we discussed the general concepts
associated with relayers in the Wormhole
ecosystem. In this section, we'll elaborate on the
considerations that should be accounted for
when using relayers in your xDapp.
Fundamentals
It's important to remember that relayers are
untrusted. This means you don't have to trust
them--but it also means you can't trust them.
This is true of both generic and specialized
relayers.
Generic Relayers
Generic relayers are a decentralized relayer
network which can deliver arbitrary VAAs as long
as the recipient contract conforms with the
generic relayer API.
Advantages:
Disadvantages:
Specialized Relayers
Specialized Relayers are relayers that are
purpose-built to relay messages for a certain
application. In the future, there may be ways to
customize generic relayers such that they will
gain the advantages of today's specialized
relayers.
Advantages:
Disadvantages
Relayer Incentives
Environment Setup
The bare minimum Wormhole environment is
just a blockchain linked up to a Guardian node.
There are quite a few ways of accomplishing this,
and if you're just looking to get your feet wet, you
should try whichever sounds easiest.
Tilt (Devnet)
What is Tilt?
Tilt is part of the official Docker ecosystem. It's a
tool which allows developers to easily configure a
Kubernetes environment for development.
Pros
Cons
Setting up Tilt
Tilt functions best in a UNIX-style environment.
For Windows users, a WSL environment is
recommended.
cd wormhole
tilt up
Using Tilt
Tilt can pretty much be treated as an external
environment / testnet that you can easily spin up
and tear down.
tilt down
Troubleshooting
Tilt, Kubernetes, and Docker may be new tools
for developers entering the Wormhole
ecosystem. This section is meant to provide
some additional support when setting up the
Wormhole Tilt environment.
macOS Install
Prerequisites
Install Homebrew if you don't already have it.
1. Install Go
brew install go
2. Install Docker
3. Install Tilt
Script Setup
If you're using a Debian distro, you should run
the dev-setup.sh script. Even if you're not using
Debian, this script still contains the main steps
for setup.
Regular Setup
1. Install Go
wget https://go.dev/dl/go1.18.1.linux-
amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local
-xzf go1.18.1.linux-amd64.tar.gz
2. Install Docker
https://docs.docker.com/engine/install/ubuntu
/#installation-methods
Install minikube .
Configure minikube:
4. Install Tilt
curl -fsSL
https://raw.githubusercontent.com/tilt-
dev/tilt/master/scripts/install.sh | bash
cd wormhole/
tilt up
cd wormhole
tilt up --host=0.0.0.0 --
--webHost=0.0.0.0
Wormhole Local
Validator
Pros
Cons
Troubleshooting
Q: Anvil isn't working
Testnet
Wormhole testnet is spread across many of the
most popular testnet blockchains.
Pros
Cons
Using Testnet
If you elect to use testnet, the Wormhole
contracts addresses can be found in the
Contracts page.
Tooling
Regardless of the development environment that
you use, there are a few wormhole-specific tools
you should know about.
Orchestrator
Wormhole SDKs
Reference Bridge UI
Explorer
Example Projects
Basic Examples
ICCO
Native Swap
Wormhole Examples
Contract Development
This section should help you get off the ground
with contract development in the Wormhole
ecosystem.
EVM
Disclaimer: This section is written as a guide for
how to use Wormhole for experienced EVM
developers. If you are new to using the EVM
ecosystem, it's recommended for you to get
started with a tutorial like this.
Frontend Development
address private
wormhole_core_bridge_address =
address(0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B)
IWormhole core_bridge =
IWormhole(wormhole_core_bridge_address);
Primary functions
The Wormhole Core Layer has two important
interactions -- (1) emit VAAs, and (2) parse and
verify VAAs that originated from other chains.
Emitting a VAA
Single VAA
Batch VAA
Token Bridge
This section will explain how to properly interact
with the Wormhome Token Bridge Module in an
EVM ecosystem.
address private
wormhole_token_bridge_address =
address(0x3ee18B2214AFF97000D974cf647E7C347E8fa585)
ITokenBridge token_bridge =
ITokenBridge(wormhole_token_bridge_address);
Basic Transfer
Basic transfer should only be used if you are
transferring tokens to an end user wallet. If the
end destination is a contract, you should only use
Contract Controlled Transfers (described below).
contractAddress.approve(token_bridge_address,
amt);
const emitterAddr =
getEmitterAddressEth(network.tokenBridgeAddress);
const seq = parseSequenceFromLogEth(tx,
network.bridgeAddress);
const vaaURL =
`${config.wormhole.restAddress}/v1
/signed_vaa/${network.wormholeChainId}
/${emitterAddr}/${seq}`;
let vaaBytes = await (await
fetch(vaaURL)).json();
while (!vaaBytes.vaaBytes) {
console.log("VAA not found, retrying in
5s!");
await new Promise((r) => setTimeout(r,
5000)); //Timeout to let Guardiand pick up
log and have VAA ready
vaaBytes = await (await
fetch(vaaURL)).json();
}
contractAddress.approve(token_bridge_address,
amt);
const emitterAddr =
getEmitterAddressEth(network.tokenBridgeAddress);
const seq = parseSequenceFromLogEth(tx,
network.bridgeAddress);
const vaaURL =
`${config.wormhole.restAddress}/v1
/signed_vaa/${network.wormholeChainId}
/${emitterAddr}/${seq}`;
let vaaBytes = await (await
fetch(vaaURL)).json();
while (!vaaBytes.vaaBytes) {
console.log("VAA not found, retrying in
5s!");
await new Promise((r) => setTimeout(r,
5000)); //Timeout to let Guardiand pick up
log and have VAA ready
vaaBytes = await (await
fetch(vaaURL)).json();
}
NFT Bridge
This section will explain how to properly interact
with the NFT Bridge Module in an EVM
ecosystem.
address private
wormhole_NFT_bridge_address =
address(0x6FFd7EdE62328b3Af38FCD61461Bbfc52F5651fE)
INFTBridge NFT_bridge =
INFTBridge(wormhole_nft_bridge_address);
Transferring a NFT
The Wormhole NFT Bridge only supports tokens
compliant with the ERC-721 interface, and
functions by creating a 'wrapped NFT' with
identical metadata. How this is implemented
varies by ecosystem.
transferNFT(tokenAddress, tokenID,
recipientChain, recipient, nonce);
const emitterAddr =
getEmitterAddressEth(network.NFTBridgeAddress);
const seq = parseSequenceFromLogEth(tx,
network.bridgeAddress);
const vaaURL =
`${config.wormhole.restAddress}/v1
/signed_vaa/${network.wormholeChainId}
/${emitterAddr}/${seq}`;
let vaaBytes = await (await
fetch(vaaURL)).json();
while (!vaaBytes.vaaBytes) {
console.log("VAA not found, retrying in
5s!");
await new Promise((r) => setTimeout(r,
5000)); //Timeout to let Guardiand pick up
log and have VAA ready
vaaBytes = await (await
fetch(vaaURL)).json();
}
completeTransfer(VAA);
Relayer Module
Disclaimer: This module is only available in
devnet, and is subject to change while still in
development.
Receiving Messages
Receiving messages through the relayer module
is almost trivial. Simply implement the public
function wormholeReciever in your contract that
the relayer module will invoke.
function wormholeReceiver(
bytes[] memory vaas,
uint16 sourceChain,
bytes32 sourceAddress,
bytes memory payload
)
Sending Messages
In order to send a message to another contract,
you must call
requestDelivery(DeliveryInstructions
instructions) . There are a few different things
you can accomplish with this call.
struct DeliveryParameters {
uint16 targetChain;
bytes32 targetAddress;
bytes payload;
VAAId[] deliveryList;
bytes relayParameters;
bytes chainPayload;
uint32 nonce;
uint8 consistencyLevel;
}
Compute Budget
Part of the relay parameters is a
'computeBudget' which specifies the maximum
amount of computation that can be spent
executing delivery on the destination contract.
This is effectively a 'gasLimit' in the EVM
ecosystem, but due to the relayer network
supporting blockchains that don't utilize the
Delivery Failures
'Delivery Failure' is a technical term in the case of
the relayer module. It does not mean 'something
went wrong', but rather that the relayer
attempted to deliver the VAA, and was
unsuccessful. There are only 3 causes of a
delivery failure.
Delivery Retries
In the unfortunate scenario of a delivery failure,
the VAAs can be re-delivered by requesting their
delivery a second time. To accomplish this,
simply list their VAA IDs in the deliveryList in
the call.
Best Practices
The Wormhole contracts were designed in a
manner such that composability is the default,
but maximizing composability requires that
xDapp developers follow certain conventions
around the sending and receiving of messages.
Sending Messages
When sending messages, you should follow the
same paradigm as is used by the Wormhole
modules, namely
Good Example
emitMyMessage(MY_OTHER_CONTRACT, 0);
token_bridge.transferTokensWithPayload(SOME_TOKEN,
SOME_AMOUNT, OTHER_CHAIN,
MY_OTHER_CONTRACT,
0, null);
relayer_contract.requestDelivery(OTHER_CHAIN,
MY_OTHER_CONTRACT, 0,
getRelayerFeeAmount());
}
Receiving Messages
The best practices for receiving messages
employ similar concepts. You should keep in
mind that other contracts might want to
integrate with your specific logic. As such, you
shouldn't tie your verification logic to the delivery
mechanism of your VAAs, and you should also
give external integrators a safe way to compose
with your module.
Critical!
Composability
Good Example
require(myTrustedContracts[vm.emitterChainId]
==
vm.emitterAddress, "Invalid
Emitter Address!");
require(parseIntendedRecipient(vm.payload)
== msg.sender);
core_bridge.parseAndVerifyBatchVM(batchVAA,
true);
core_bridge.clearBatchCache(vm2.hashes);
}
Specialized Relayers
Rather than home-rolling a relayer, it's
recommended that integrators start from the
existing Spy Relayer provided in the Wormhole
Core Repository.
Wormhole Typescript
SDK
A Wormhole Typescript SDK provided for
applications that only need to interact with the
Core and Token Bridge contracts off-chain.
npm i @certusone/wormhole-sdk
Registering Tokens
Registering tokens with the token bridge can be
done from any supported blockchain, and only
needs to be done once - globally - per token. This
is is typically done via a UI (such as Portal) rather
than done on-chain.
const emitterAddr =
getEmitterAddressEth(network.tokenBridgeAddress);
const seq = parseSequenceFromLogEth(
networkTokenAttestation,
network.bridgeAddress
);
const vaaURL =
`${config.wormhole.restAddress}/v1
/signed_vaa/${network.wormholeChainId}
/${emitterAddr}/${seq}`;
console.log("Searching for: ", vaaURL);
let vaaBytes = await (await
fetch(vaaURL)).json();
while (!vaaBytes.vaaBytes) {
console.log("VAA not found, retrying in
5s!");
await new Promise((r) => setTimeout(r,
5000)); //Timeout to let Guardiand pick up
log and have VAA ready
vaaBytes = await (await
fetch(vaaURL)).json();
}
await targetTokenBridge.createWrapped(
Buffer.from(vaaBytes.vaaBytes,
"base64"),
{
gasLimit: 2000000,
}
);
await new Promise((r) => setTimeout(r,
5000)); //Time out to let block propogate
const wrappedTokenAddress = await
targetTokenBridge.wrappedAsset(
network.wormholeChainId,
Buffer.from(tryNativeToHexString(network.testToken,
"ethereum"), "hex")
);
console.log("Wrapped token created at: ",
wrappedTokenAddress);
Token Transfers
Before transferring tokens, you should ensure
that the token is registered on the chain you are
transferring to, and that any necessary
prerequisite steps (such as sending token
approvals or creating associated token accounts)
have already been done.
await
treasury.approveTokenBridge(bridgeAmt, {
gasLimit: 2000000,
});
tryNativeToHexString(targetDeployment.deployedAddre
"ethereum"),
"hex"
);
const tx = await (
await treasury.bridgeToken(
bridgeAmt,
targetNetwork.wormholeChainId,
targetRecepient
)
).wait();
const emitterAddr =
getEmitterAddressEth(network.tokenBridgeAddress);
const seq = parseSequenceFromLogEth(tx,
network.bridgeAddress);
const vaaURL =
`${config.wormhole.restAddress}/v1
/signed_vaa/${network.wormholeChainId}
/${emitterAddr}/${seq}`;
let vaaBytes = await (await
fetch(vaaURL)).json();
while (!vaaBytes.vaaBytes) {
console.log("VAA not found, retrying in
5s!");
await new Promise((r) => setTimeout(r,
5000)); //Timeout to let Guardiand pick up
log and have VAA ready
vaaBytes = await (await
fetch(vaaURL)).json();
}
Cross-Ecosystem
Token Transfer
A defining feature of cross chain apps (xDapps) is
the ability to move tokens from one chain to
another, even if those blockchains have radically
different virtual machine models.
import {
Token,
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import {
getForeignAssetSolana,
hexToUint8Array,
nativeToHexString,
CHAIN_ID_ETH,
} from "@certusone/wormhole-sdk";
const SOLANA_TOKEN_BRIDGE_ADDRESS =
"wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"
// determine destination address - an
associated token account
const solanaMintKey = new PublicKey(
(await getForeignAssetSolana(
connection,
SOLANA_TOKEN_BRIDGE_ADDRESS,
CHAIN_ID_ETH,
hexToUint8Array(nativeToHexString(tokenAddress,
CHAIN_ID_ETH) || "")
)) || ""
);
const recipientAddress = await
Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
solanaMintKey,
recipientWalletAddress
);
import {
trasnferFromEth,
parseSequenceFromLogEth,
getEmitterAddressEth,
CHAIN_ID_SOLANA,
} from "@certusone/wormhole-sdk";
const ETH_TOKEN_BRIDGE_ADDRESS =
"0x3ee18B2214AFF97000D974cf647E7C347E8fa585"
const SOL_BRIDGE_ADDRESS =
"worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"
await postVaaSolana(
connection, // Solana Mainnet Connection
wallet, //Solana Wallet Signer
SOL_BRIDGE_ADDRESS,
payerAddress,
signedVAA
);
Using Relayers
In this example, we’ll utilize the token bridge
relayer network to complete a token transfer
from Polygon and to Oasis.
const transferAmount =
BigNumber.from("1000000000000000000"); //
We are sending 1 MATIC over the wall to
Oasis
const relayerFeeSchedule = await(
await fetch(
"https://raw.githubusercontent.com
/certusone/wormhole-relayer-list/main
/relayer.json"
)
).json();
interface ChainAddress {
chainId: number;
address: string;
coingeckoId: string;
}
interface Relayer {
name: string;
url: string;
}
interface FeeSchedule {
[chainId: string]: {
type: "flat" | "percent";
feeUsd?: number;
feePercent?: number;
gasEstimate?: number;
};
}
(relayerFeeSchedule.feeSchedule[CHAIN_ID_OASIS].fee
/ 100) *
transferAmount.toNumber();
}
let overrides;
let feeData = await
PolygonWallet.provider.getFeeData();
overrides = {
maxFeePerGas:
feeData.maxFeePerGas?.mul(50) ||
undefined,
maxPriorityFeePerGas:
feeData.maxPriorityFeePerGas?.mul(50) ||
undefined,
};
const POLYGON_TOKEN_BRIDGE =
"0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE"
const POLYGON_CORE_BRIDGE_ADDRESS =
"0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7"
const sequence =
parseSequenceFromLogEth(receipt,
POLYGON_CORE_BRIDGE_ADDRESS);
const emitterAddress =
getEmitterAddressEth(POLYGON_TOKEN_BRIDGE);
console.log("Sequence: ", sequence);
console.log("EmitterAddress: ",
emitterAddress);
BigNumber.from(feeWei.toString()) identifies
the fee in smallest unit of the network for the
relayer.
console.log("VAA Relayed!");
Other Resources
Here is a collection of other resources and
reference sources which you're likely to find
helpful.
Glossary
Disclaimer: In some instances, Wormhole uses
general terms for decentralized, cross-chain
elements as branded verbiage. In most casese, the
definition of the general term does not differ from
Wormhole's definition though Wormhole's
definitions may be more narrow than general
interpretations.
Design Documents
Testnet
Testnet Bridge UI
Tilt
https://github.com/wormhole-foundation
/wormhole.
Wormhole Explorer
Wormhole SDK
Contracts
Here you can find the addresses for the deployed
contracts on all the chains that Wormhole
supports, including testnet.
Mainnet
Core Bridge
Chain Wormhole
Network ID
Name Chain ID
mainnet-
Solana 1
beta
Ethereum 2 1
Terra
3 columbus-5
Classic
Binance
Smart 4 56
Chain
Polygon 5 137
Avalanche
6 43114
(C-Chain)
Oasis
7 4262
(Emerald)
Aurora 9 1313161554
Fantom 10 250
Karura 11 686
Acala 12 787
Klaytn 13 8217
Celo 14 42220
Chain Wormhole
Network ID
Name Chain ID
NEAR 15
Moonbeam 16 1284
Terra 18 phoenix-1
Aptos 22
Token Bridge
Chain Wormhole
Network ID
Name Chain ID
mainnet-
Solana 1
beta
Ethereum 2 1
Terra 3 columbus-5
Binance
Smart 4 56
Chain
Polygon 5 137
Avalanche
6 43114
(C-Chain)
Oasis
7 4262
(Emerald)
Aurora 9 1313161554
Fantom 10 250
Karura 11 686
Chain Wormhole
Network ID
Name Chain ID
Acala 12 787
Klaytn 13 8217
Celo 14 42220
NEAR 15
Moonbeam 16 1284
Terra 18 phoenix-1
Aptos 22
NFT Bridge
Chain Wormhole
Network ID
Name Chain ID
mainnet-
Solana 1
beta
Ethereum 2 1
Binance
Smart 4 56
Chain
Polygon 5 137
Avalanche
6 43114
(C-Chain)
Oasis
7 4262
(Emerald)
Aurora 9 1313161554
Fantom 10 250
Karura 11 686
Acala 12 787
Klaytn 13 8217
Moonbeam 16 1284
Celo 14 42220
Testnet
Core Bridge
Chain Wormhole
Network ID
Name Chain ID
Solana 1 devnet
Ethereum
2 5
(Goerli)
Ethereum
10001 3
(Ropsten)
Terra 3 bombay-12
Binance
Smart 4 97
Chain
Polygon
5 80001
(Mumbai)
Avalanche
6 43113
(Fuji)
Oasis
(Emerald 7 42261
Testnet)
Algorand
8
(Testnet)
Aurora 9 1313161555
Fantom 10 4002
Karura 11 686
Acala 12 787
Klaytn 13 1001
Celo 14 44787
NEAR 15
Moonbase
16 1287
alpha
Terra 18 pisco-1
Injective 19 testnet
Aptos 22
Token Bridge
Chain Wormhole
Network ID
Name Chain ID
Solana 1 devnet
Ethereum
2 5
(Goerli)
Ethereum
10001 3
(Ropsten)
Terra 3 bombay-12
Binance
Smart 4 97
Chain
Polygon
5 80001
(Mumbai)
Avalanche
6 43113
(Fuji)
Oasis
(Emerald 7 42261
Testnet)
Algorand
8
(Testnet)
Aurora 9 1313161555
Fantom 10 4002
Karura 11 686
Acala 12 787
Klaytn 13 1001
Celo 14 44787
Near 15
Moonbase
16 1287
alpha
Injective 19 testnet
Aptos 22
NFT Bridge
Chain Wormhole
Network ID
Name Chain ID
Solana 1 devnet
Chain Wormhole
Network ID
Name Chain ID
Ethereum
2 5
(Goerli)
Ethereum
10001 3
(Ropsten)
Binance
Smart 4 97
Chain
Polygon
5 80001
(Mumbai)
Avalanche
6 43113
(Fuji)
Oasis
(Emerald 7 42261
Testnet)
Aurora 9 1313161555
Fantom 10 4002
Karura 11 686
Acala 12 787
Klaytn 13 1001
Celo 14 44787
Moonbase
16 1287
alpha
Devnet / Tilt
Core Bridge
Wormhole Network
Chain Name
Chain ID ID
Solana 1
Ethereum 2
Terra 3
Binance Smart
4
Chain
Wormhole Network
Chain Name
Chain ID ID
Algorand 8
NEAR 15
Terra2 18
Aptos 22
Wormholechain 3104
Token Bridge
Wormhole Network
Chain Name
Chain ID ID
Solana 1
Ethereum 2
Terra 3
Binance Smart
4
Chain
Algorand 8
NEAR 15
Terra2 18
Aptos 22
Wormholechain 3104
NFT Bridge
Blockchain Finality
Recommendations
The goal of Wormhole is to provide high
confidence that only finalized messages are
observed and attested. Different chains use
different consensus mechanisms and so there
are different finality assumptions with each one.
Suggested
Chain Wormhole Number of
Name Chain ID Block
Confirmations
Solana 1 32
Ethereum 2 15
Terra
3 Instant
Classic
Binance
Smart 4 15
Chain
Polygon 5 512
Avalanche
6 1
(C-Chain)
Oasis
7 1
(Emerald)
Aurora 9 1
Fantom 10 1
Karura 11 1
Acala 12 1
Klaytn 13 1
Suggested
Chain Wormhole Number of
Name Chain ID Block
Confirmations
Celo 14 1
Terra 18 Instant
RPC Nodes
These RPC nodes are maintained by the
Guardians to help fetch VAAs and query the
Wormhole network.
https://wormhole-v2-mainnet-api.certus.one
https://wormhole.inotel.ro
https://wormhole-v2-mainnet-api.mcf.rocks
https://wormhole-v2-mainnet-
api.chainlayer.network
https://wormhole-v2-mainnet-
api.staking.fund
https://wormhole-v2-mainnet.01node.com
https://wormhole-v2-testnet-api.certus.one
0x13947Bd48b18E53fdAeEe77F3473391aC727C638